开放的编程资料库

当前位置:我爱分享网 > Python教程 > 正文

Python 命名元组

Python命名元组教程展示了如何在Python中使用命名元组。

Python命名元组

Pythonnamedtuple是一种不可变的容器类型,可以使用索引和命名属性访问其值。它具有像元组一样的功能和附加功能。命名元组是使用collections.namedtuple工厂函数创建的。

命名元组本质上是易于创建的、不可变的、轻量级的对象类型。命名元组可用于使代码更简洁和Pythonic。它们类似于其他语言(C#、Java)中的记录。

Pythonnamedtuple基本示例

以下是一个带有命名元组的简单示例。

#!/usr/bin/python

from collections import namedtuple


City = namedtuple('City' , 'name population')

c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)

print(c1)
print(c2)

示例创建城市命名元组。

from collections import namedtuple

首先,我们从collections模块导入namedtuple类型。

City = namedtuple('City' , 'name population')

我们定义了命名元组。第一个参数是命名元组的名称。第二个参数是字段名称。这些可以在字符串'namepopulation'或列表['name','population']中指定。

c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)

这里我们创建了两个namedtuple对象。

$ ./basic.py 
City(name='Bratislava', population=432000)
City(name='Budapest', population=1759000)

Python命名元组访问

可以使用索引及其命名属性访问命名元组。

#!/usr/bin/python

from collections import namedtuple


City = namedtuple('City' , 'name population')

c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)

print(c1[0])
print(c1[1])

print(c2.name)
print(c2.population)

在示例中,我们演示了这两种方式。

$ ./accessing.py 
Bratislava
432000
Budapest
1759000

Pythonnamedtuple解包

解包是将可迭代元素存储到变量或函数参数中。

#!/usr/bin/python

from collections import namedtuple


City = namedtuple('City' , 'name population')

c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)

name, population = c1
print(f'{name}: {population}')

print('----------------------')

print(c2)
print(*c2, sep=': ')

在示例中,我们解压命名元组。

name, population = c1

这里我们将c1namedtuple解包为两个变量。

print(*c2, sep=': ')

在这里,我们使用*运算符将c2namedtuple解压缩到print函数参数中,这些参数与给定的分隔符连接到最终输出中。

$ ./unpacking.py 
Bratislava: 432000
----------------------
City(name='Budapest', population=1759000)
Budapest: 1759000
#!/usr/bin/python

from collections import namedtuple


City = namedtuple('City' , 'name population')

d = { 'name': 'Bratislava', 'population': 432000}

c = City(**d)
print(c)

使用**运算符,我们可以将字典解压为命名元组的参数。

Pythonnamedtuple子类化

由于命名元组建立在常规类之上,我们可以向它们添加功能。

#!/usr/bin/python

from collections import namedtuple
from math import sqrt

class Point(namedtuple('Point', 'x y')):

    __slots__ = ()

    @property
    def hypot(self):
        return sqrt((self.x ** 2 + self.y ** 2))

    def __str__(self):
        return f'Point: x={self.x}  y={self.y}  hypot={self.hypot}'


p = Point(5, 5)
print(p.hypot)
print(p)

我们有一个Point命名元组。我们向其添加hypot属性。

$ ./subclassing.py 
7.0710678118654755
Point: x=5  y=5  hypot=7.0710678118654755

Python打字.NamedTuple

从Python3.6开始,我们可以使用typing.NamedTuple来创建一个namedtuple。

#!/usr/bin/python

from typing import NamedTuple


class City(NamedTuple):
    name: str
    population: int


c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)

print(c1)
print(c2)

在示例中,我们有一个继承自typing.NamedTuple的City类。属性具有类型提示。

Pythonnamedtuple默认值

defaults参数可用于为字段提供默认值。

#!/usr/bin/python

from collections import namedtuple
from math import sqrt

class Point(namedtuple('Point', 'x y', defaults=[1, 1])):

    __slots__ = ()

    @property
    def hypot(self):
        return sqrt((self.x ** 2 + self.y ** 2))

    def __str__(self):
        return f'Point: x={self.x}  y={self.y}  hypot={self.hypot}'


p1 = Point(5, 5)
print(p1)

p2 = Point()
print(p2)

x和y的默认值为1。

$ ./defaults.py 
Point: x=5  y=5  hypot=7.0710678118654755
Point: x=1  y=1  hypot=1.4142135623730951

Python命名元组助手

Python为命名元组提供了几个辅助方法。

#!/usr/bin/python

from typing import NamedTuple


class Point(NamedTuple):

    x: int = 1
    y: int = 1


p = Point(5, 5)

print(p._fields)
print(p._field_defaults)
print(p._asdict())

_fields是列出字段名称的字符串元组。_field_defaults是将字段名称映射到默认值的字典。_asdict方法返回一个新的有序字典,它将字段名称映射到它们对应的值。

$ ./helpers.py 
('x', 'y')
{'x': 1, 'y': 1}
OrderedDict([('x', 5), ('y', 5)])

Pythonnamedtuple-序列化为JSON

_asdict方法可用于将命名元组序列化为JSON格式。

#!/usr/bin/python

from typing import NamedTuple
import json


class City(NamedTuple):
    name: str
    population: int


c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)
c3 = City('Prague', 1280000)
c4 = City('Warsaw', 1748000)

cities = [c1, c2, c3, c4]

print(json.dumps(c1._asdict()))

json_string = json.dumps([city._asdict() for city in cities])
print(json_string)

json.dumps方法的帮助下,我们序列化了一个城市和一个城市列表。

$ ./json_output.py 
{"name": "Bratislava", "population": 432000}
[{"name": "Bratislava", "population": 432000}, {"name": "Budapest", "population": 1759000}, 
{"name": "Prague", "population": 1280000}, {"name": "Warsaw", "population": 1748000}]

Python命名元组排序

在下面的示例中,我们对命名元组列表进行排序。

#!/usr/bin/python

from typing import NamedTuple


class City(NamedTuple):
    id: int
    name: str
    population: int


c1 = City(1, 'Bratislava', 432000)
c2 = City(2, 'Budapest', 1759000)
c3 = City(3, 'Prague', 1280000)
c4 = City(4, 'Warsaw', 1748000)
c5 = City(5, 'Los Angeles', 3971000)
c6 = City(6, 'Edinburgh', 464000)
c7 = City(7, 'Berlin', 3671000)

cities = [c1, c2, c3, c4, c5, c6, c7]

cities.sort(key=lambda e: e.name)

for city in cities:
    print(city)

借助sort方法和lambda函数,我们按城市名称对城市进行排序。

$ ./sorting.py 
City(id=7, name='Berlin', population=3671000)
City(id=1, name='Bratislava', population=432000)
City(id=2, name='Budapest', population=1759000)
City(id=6, name='Edinburgh', population=464000)
City(id=5, name='Los Angeles', population=3971000)
City(id=3, name='Prague', population=1280000)
City(id=4, name='Warsaw', population=1748000)

城市按名称升序排列。

Pythonnamedtuple_make助手

_make是一种从现有序列或可迭代对象中创建命名元组新实例的方法。

#!/usr/bin/python

from collections import namedtuple


City = namedtuple('City' , 'name population')

c1 = City._make(('Bratislava', 432000))
c2 = City._make(('Budapest', 1759000))

print(c1)
print(c2)

该示例借助_make方法从元组创建City命名元组。

Pythonnamedtuple-读取CSV数据

Python命名元组在我们读取CSV数据时很有用。

Bratislava, 432000
Budapest, 1759000
Prague, 1280000
Warsaw, 1748000
Los Angeles, 3971000
New York, 8550000
Edinburgh, 464000
Berlin, 3671000

我们有这个CSV文件。

#!/usr/bin/python

from collections import namedtuple
import csv


City = namedtuple('City' , 'name population')

f = open('cities.csv', 'r')

with f:

    reader = csv.reader(f)
    
    for city in map(City._make, reader):
        print(city)

我们使用map_make函数来创建干净的代码。

$ ./read_csv.py 
City(name='Bratislava', population=' 432000')
City(name='Budapest', population=' 1759000')
City(name='Prague', population=' 1280000')
City(name='Warsaw', population=' 1748000')
City(name='Los Angeles', population=' 3971000')
City(name='New York', population=' 8550000')
City(name='Edinburgh', population=' 464000')
City(name='Berlin', population=' 3671000')

Pythonnamedtuple-读取SQLite数据库

在下面的例子中,我们使用一个namedtuple从SQLite数据库中读取数据。

DROP TABLE IF EXISTS cities;
CREATE TABLE cities(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, 
  population INTEGER);

INSERT INTO cities(name, population) VALUES('Bratislava', 432000);
INSERT INTO cities(name, population) VALUES('Budapest', 1759000);
INSERT INTO cities(name, population) VALUES('Prague', 1280000);
INSERT INTO cities(name, population) VALUES('Warsaw', 1748000);
INSERT INTO cities(name, population) VALUES('Los Angeles', 3971000);
INSERT INTO cities(name, population) VALUES('New York', 8550000);
INSERT INTO cities(name, population) VALUES('Edinburgh', 464000);
INSERT INTO cities(name, population) VALUES('Berlin', 3671000);

这些是创建cities表的SQL语句。

$ sqlite3 ydb.db
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> .read cities.sql

使用sqlite3命令行工具,我们生成SQLite数据库和cities表。

#!/usr/bin/python

from typing import NamedTuple
import sqlite3 as sqlite


class City(NamedTuple):
    
    id: int
    name: str
    population: int


con = sqlite.connect('ydb.db')

with con:

    cur = con.cursor()

    cur.execute('SELECT * FROM cities')
    
    for city in map(City._make, cur.fetchall()):
        print(city)

我们从cities表中读取所有数据,并将每个表行转换为一个Citynamedtuple。

在本教程中,我们使用了Pythonnamedtuple。

列出所有Python教程。

未经允许不得转载:我爱分享网 » Python 命名元组

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏