Python中的“命名元组”是什么?

阅读Python 3.1中更改后 ,我发现了一些意外…… html

sys.version_info元组如今是一个命名的元组python

我之前从未据说过命名元组,而且我认为元素能够经过数字(例如在元组和列表中)或经过键(例如在字典中)进行索引。 我从未想到它们能够同时被索引。 函数

所以,个人问题是: spa

  • 什么叫元组?
  • 如何使用它们?
  • 为何/什么时候应该使用命名元组而不是普通元组?
  • 为何/什么时候应该使用普通元组而不是命名元组?
  • 是否有某种“命名列表”(命名元组的可变版本)?

#1楼

namedtuple是用于建立元组类的工厂函数 。 经过该类,咱们能够建立可经过名称调用的元组。 code

import collections

#Create a namedtuple class with names "a" "b" "c"
Row = collections.namedtuple("Row", ["a", "b", "c"], verbose=False, rename=False)   

row = Row(a=1,b=2,c=3) #Make a namedtuple from the Row class we created

print row    #Prints: Row(a=1, b=2, c=3)
print row.a  #Prints: 1
print row[0] #Prints: 1

row = Row._make([2, 3, 4]) #Make a namedtuple from a list of values

print row   #Prints: Row(a=2, b=3, c=4)

#2楼

在Python内部,有一个很好使用的容器,称为命名元组,它可用于建立类的定义,并具备原始元组的全部功能。 htm

使用命名元组将直接应用于默认的类模板以生成一个简单的类,此方法容许使用大量代码来提升可读性,而且在定义类时也很是方便。 对象


#3楼

命名元组容许向后兼容检查此类版本的代码 索引

>>> sys.version_info[0:2]
(3, 1)

同时经过使用此语法使未来的代码更明确 ip

>>> sys.version_info.major
3
>>> sys.version_info.minor
1

#4楼

命名元组基本上是易于建立的轻量级对象类型。 可使用类对象变量解引用或标准元组语法来引用已命名的元组实例。 除了它们是不可变的,它们能够相似地用于struct或其余常见记录类型。 它们是在Python 2.6和Python 3.0中添加的,尽管在Python 2.4中实现秘诀ci

例如,一般将点表示为元组(x, y) 。 这致使以下代码:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)

使用命名元组,它变得更具可读性:

from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)

可是,命名元组仍然与普通元组向后兼容,所以如下内容仍然有效:

Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
# use index referencing
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
 # use tuple unpacking
x1, y1 = pt1

所以, 在您认为对象表示法将使您的代码更具pythonic性且更易于阅读的任何地方都应使用命名元组代替元组 。 我我的已经开始使用它们来表示很是简单的值类型,尤为是在将它们做为参数传递给函数时。 它使函数更具可读性,而看不到元组包装的上下文。

此外, 您还能够替换没有功能的普通不可变 ,仅将它们替换为字段。 您甚至能够将命名的元组类型用做基类:

class Point(namedtuple('Point', 'x y')):
    [...]

可是,与元组同样,命名元组中的属性是不可变的:

>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute

若是要可以更改值,则须要另外一种类型。 对于可变记录类型 ,有一个方便的用法 ,可以让您为属性设置新值。

>>> from rcdtype import *
>>> Point = recordtype('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
>>> print(pt1[0])
    2.0

可是,我不知道有任何形式的“命名列表”可以让您添加新字段。 在这种状况下,您可能只想使用字典。 可使用pt1._asdict()将命名的元组转换为字典,该pt1._asdict()返回{'x': 1.0, 'y': 5.0}而且可使用全部经常使用的字典功能进行操做。

如前所述,您应该查看文档以获取构成这些示例的更多信息。


#5楼

namedtuple是一个很棒的功能,它们是数据的完美容器。 当您必须“存储”数据时,可使用元组或字典,例如:

user = dict(name="John", age=20)

要么:

user = ("John", 20)

字典方法是压倒性的,由于字典比元组易变且慢。 另外一方面,元组是不可变的且轻量级的,可是对于数据字段中的大量条目却缺少可读性。

namedtuple是这两种方法的完美折衷,它们具备出色的可读性,轻巧性和不变性(并且它们是多态的!)。

相关文章
相关标签/搜索