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
这里我们将c1
namedtuple解包为两个变量。
print(*c2, sep=': ')
在这里,我们使用*
运算符将c2
namedtuple解压缩到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
表中读取所有数据,并将每个表行转换为一个City
namedtuple。
在本教程中,我们使用了Pythonnamedtuple。
列出所有Python教程。