pin_drop当前位置:知识文库 ❯ 图文
Python元组命名namedtuple
一、概述
命名元组(Named Tuple)是 collections 模块提供的工厂函数,用于创建具有字段名的元组子类。它既保留了普通元组的不可变性、内存高效和可解包等特性,又增加了通过字段名访问元素的能力,使代码更加清晰易读。
二、创建命名元组
基本创建
代码示例
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 5)
print(p)
print(type(p))输出:
代码示例
Point(x=3, y=5)
<class '__main__.Point'>不同的字段名定义方式
代码示例
from collections import namedtuple
# 方式1:列表
Person1 = namedtuple("Person", ["name", "age"])
# 方式2:字符串(空格分隔)
Person2 = namedtuple("Person", "name age")
# 方式3:字符串(逗号分隔)
Person3 = namedtuple("Person", "name, age")
p1 = Person1("Alice", 25)
p2 = Person2("Bob", 30)
p3 = Person3("Charlie", 35)
print(p1, p2, p3)输出:
代码示例
Person(name='Alice', age=25) Person(name='Bob', age=30) Person(name='Charlie', age=35)三、访问字段
通过字段名访问
代码示例
from collections import namedtuple
Student = namedtuple("Student", ["name", "score", "grade"])
s = Student("Alice", 95, "A")
print(s.name)
print(s.score)
print(s.grade)输出:
代码示例
Alice
95
A通过索引访问
代码示例
print(s[0])
print(s[1])
print(s[2])输出:
代码示例
Alice
95
A解包访问
代码示例
name, score, grade = s
print(name, score, grade)输出:
代码示例
Alice 95 A四、常用方法
_make 方法
从可迭代对象创建命名元组:
代码示例
data = ["Bob", 88, "B"]
s = Student._make(data)
print(s)输出:
代码示例
Student(name='Bob', score=88, grade='B')_asdict 方法
将命名元组转换为有序字典:
代码示例
s = Student("Alice", 95, "A")
d = s._asdict()
print(d)
print(type(d))输出:
代码示例
{'name': 'Alice', 'score': 95, 'grade': 'A'}
<class 'dict'>_fields 属性
查看所有字段名:
代码示例
print(Student._fields)输出:
代码示例
('name', 'score', 'grade')_replace 方法
创建新实例替换指定字段(原实例不变):
代码示例
s1 = Student("Alice", 95, "A")
s2 = s1._replace(score=88, grade="B")
print("原实例:", s1)
print("新实例:", s2)输出:
代码示例
原实例: Student(name='Alice', score=95, grade='A')
新实例: Student(name='Alice', score=88, grade='B')五、与普通元组对比
代码示例
# 普通元组
point1 = (3, 5)
print(point1[0], point1[1])
# 命名元组
Point = namedtuple("Point", ["x", "y"])
point2 = Point(3, 5)
print(point2.x, point2.y)六、注意事项
提示:不可变。命名元组是不可变的,不能修改字段值。需要修改时应使用
_replace()创建新实例。
提示:字段名限制。字段名必须是合法的 Python 标识符,不能以
_开头,不能与 Python 关键字冲突。
提示:不是字典。命名元组比字典更节省内存,但不适合需要频繁修改的场景。
提示:继承。命名元组是元组的子类,
isinstance(point, tuple)返回True。
七、小结
-
创建方式:通过
namedtuple()创建,具有字段名和不可变性 -
访问方式:支持字段名访问、索引访问和解包访问
-
常用方法:
_make从可迭代对象创建,_asdict转为字典,_replace替换字段 -
优势:比普通元组可读性更高,比字典更节省内存
八、练习题
练习1
创建一个命名元组 Circle,包含字段 center(一个 Point 命名元组)和 radius。编写函数计算圆的面积和周长。
练习2
给定一个 CSV 格式的学生数据列表 rows = [("Alice", 95), ("Bob", 88), ("Charlie", 72)],使用 _make 方法将每行转换为命名元组,然后使用 _asdict 方法转为字典列表,最后使用 _replace 将所有低于 80 分的成绩替换为 80。
练习参考答案
练习1:使用 Circle = namedtuple("Circle", ["center", "radius"]),面积 math.pi * r**2,周长 2 * math.pi * r
练习2:遍历rows使用Student._make(row)创建,再s._replace(score=max(s.score, 80))替换
常见问题
命名元组和dataclass有什么区别?
命名元组是不可变的,继承自tuple,内存占用更小;dataclass默认是可变的(可以设置frozen=True变为不可变),内存占用较大但功能更强大。如果只是存储简单不可变数据,命名元组更轻量;如果需要复杂功能如默认值、方法定义等,dataclass更适合。
命名元组可以继承吗?
命名元组本身已经是tuple的子类,不支持直接继承。但可以在创建namedtuple时使用rename=True参数处理字段名冲突,或者使用类方法为命名元组添加自定义行为。
命名元组的方法为什么以下划线开头?
以下划线开头是为了避免与用户定义的字段名冲突。如果方法名不加下划线,当用户的字段名恰好与方法名相同时就会产生问题。这是Python命名元组的命名约定。
命名元组适合什么场景?
适合存储简单的不可变记录型数据,如数据库记录、配置项、坐标点、RGB颜色等。当需要比普通元组更好的可读性,但又不想使用字典的内存开销时,命名元组是理想选择。
小贴士
在Python 3.7+中,命名元组的_asdict()方法返回的是普通字典而不是有序字典。如果你需要保持字段顺序,不用担心,Python 3.7+的字典本身就保持插入顺序。命名元组在数据处理和CSV读取场景中特别实用。
本文涉及AI创作
内容由AI创作,请仔细甄别