什么是命名元组,我如何使用它们? 什么时候我应该使用命名元组而不是正常的元组,反之亦然? 也有“名单”吗?(即可变命名元组)


关于最后一个问题,请参见Python中是否存在可变命名元组。


当前回答

试试这个:

collections.namedtuple()

基本上,命名元组很容易创建,轻量级的对象类型。 它们将元组转换为用于简单任务的方便容器。 使用namedtuples,您不必使用整数索引访问元组的成员。

例子:

代码1:

>>> from collections import namedtuple

>>> Point = namedtuple('Point','x,y')

>>> pt1 = Point(1,2)

>>> pt2 = Point(3,4)

>>> dot_product = ( pt1.x * pt2.x ) +( pt1.y * pt2.y )

>>> print dot_product
11

代码2:

>>> from collections import namedtuple

>>> Car = namedtuple('Car','Price Mileage Colour Class')

>>> xyz = Car(Price = 100000, Mileage = 30, Colour = 'Cyan', Class = 'Y')

>>> print xyz

Car(Price=100000, Mileage=30, Colour='Cyan', Class='Y')
>>> print xyz.Class
Y

其他回答

命名元组是一个很好的特性,它们是数据的完美容器。当你必须“存储”数据时,你会使用元组或字典,比如:

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

or:

user = ("John", 20)

字典方法是压倒性的,因为字典是可变的,比元组慢。另一方面,元组是不可变和轻量级的,但是对于数据字段中的大量条目缺乏可读性。

命名元组是这两种方法的完美折衷,它们具有很高的可读性、轻量级性和不可变性(而且它们是多态的!)

在Python里面有一个很好的使用容器叫做命名元组,它可以用来创建一个类的定义,并具有原始元组的所有功能。

使用命名的tuple将直接应用到默认的类模板来生成一个简单的类,这种方法允许大量的代码来提高可读性,并且在定义类时也非常方便。

试试这个:

collections.namedtuple()

基本上,命名元组很容易创建,轻量级的对象类型。 它们将元组转换为用于简单任务的方便容器。 使用namedtuples,您不必使用整数索引访问元组的成员。

例子:

代码1:

>>> from collections import namedtuple

>>> Point = namedtuple('Point','x,y')

>>> pt1 = Point(1,2)

>>> pt2 = Point(3,4)

>>> dot_product = ( pt1.x * pt2.x ) +( pt1.y * pt2.y )

>>> print dot_product
11

代码2:

>>> from collections import namedtuple

>>> Car = namedtuple('Car','Price Mileage Colour Class')

>>> xyz = Car(Price = 100000, Mileage = 30, Colour = 'Cyan', Class = 'Y')

>>> print xyz

Car(Price=100000, Mileage=30, Colour='Cyan', Class='Y')
>>> print xyz.Class
Y

namedtuple

是清理代码并使其更具可读性的最简单方法之一。它自我记录元组中发生的事情。Namedtuples实例的内存效率与常规元组一样高,因为它们没有每个实例的字典,这使得它们比字典更快。

from collections import namedtuple

Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])

 p = Color(170, 0.1, 0.6)
 if p.saturation >= 0.5:
     print "Whew, that is bright!"
 if p.luminosity >= 0.5:
     print "Wow, that is light"

如果不给元组中的每个元素命名,它就像这样:

p = (170, 0.1, 0.6)
if p[1] >= 0.5:
    print "Whew, that is bright!"
if p[2]>= 0.5:
   print "Wow, that is light"

要理解第一个例子中发生的事情要困难得多。使用namedtuple,每个字段都有一个名称。并且通过名称而不是位置或索引访问它。不叫p[1],叫p饱和。这样更容易理解。看起来更干净。

创建namedtuple的实例比创建字典容易。

# dictionary
>>>p = dict(hue = 170, saturation = 0.1, luminosity = 0.6)
>>>p['hue']
170

#nametuple
>>>from collections import namedtuple
>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)
>>>p.hue
170

什么时候可以使用namedtuple

正如刚才所述,namedtuple使我们更容易理解元组 更容易。因此,如果需要引用元组中的项,则 将它们创建为命名元组是有意义的。 除了比字典更轻量级之外,命名元组也 不像字典那样有顺序。 与上面的示例一样,创建的实例更为简单 命名元组而不是字典。并引用已命名的项目 Tuple看起来比字典更简洁。P.hue而不是 p(“色相”)。

的语法

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])

namedtuple is in the collections library. typename: This is the name of the new tuple subclass. field_names: A sequence of names for each field. It can be a sequence as in a list ['x', 'y', 'z'] or string x y z (without commas, just whitespace) or x, y, z. rename: If rename is True, invalid fieldnames are automatically replaced with positional names. For example, ['abc', 'def', 'ghi','abc'] is converted to ['abc', '_1', 'ghi', '_3'], eliminating the keyword 'def' (since that is a reserved word for defining functions) and the duplicate fieldname 'abc'. verbose: If verbose is True, the class definition is printed just before being built.

如果你选择的话,你仍然可以通过命名元组的位置来访问它们。P [1] == P饱和。它仍然像常规元组一样解包。

方法

支持所有常规元组方法。例如:min(), max(), len(), in, not in,拼接(+),索引,切片等。namedtuple还有一些额外的。注意:这些都以下划线开头。_replace, _make, _asdict。

_replace 返回命名元组的新实例,用新值替换指定字段。

的语法

somenamedtuple._replace(kwargs)

例子

>>>from collections import namedtuple

>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)

>>>p._replace(hue=87)
Color(87, 0.1, 0.6)

>>>p._replace(hue=87, saturation=0.2)
Color(87, 0.2, 0.6)

注意:字段名不加引号;它们是关键字。 记住:元组是不可变的——即使它们是命名元组并且有_replace方法。_replace生成一个新实例;它不修改原始值或替换旧值。当然,您可以将新结果保存到变量中。P = P ._replace(hue=169)

_make

从现有序列或可迭代对象中创建一个新实例。

的语法

somenamedtuple._make(iterable)

例子

 >>>data = (170, 0.1, 0.6)
 >>>Color._make(data)
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make([170, 0.1, 0.6])  #the list is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make((170, 0.1, 0.6))  #the tuple is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make(170, 0.1, 0.6) 
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<string>", line 15, in _make
TypeError: 'float' object is not callable

上一个怎么样了?括号内的项应该是可迭代对象。因此,括号内的列表或元组可以工作,但没有作为可迭代对象封装的值序列将返回错误。

_asdict

返回一个新的OrderedDict,它将字段名映射到相应的值。

的语法

somenamedtuple._asdict()

例子

 >>>p._asdict()
OrderedDict([('hue', 169), ('saturation', 0.1), ('luminosity', 0.6)])

参考:https://www.reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/

还有一个命名列表,它类似于命名元组,但是是可变的 https://pypi.python.org/pypi/namedlist

我认为添加使用类型提示的NamedTuples的信息是值得的:

# dependencies
from typing import NamedTuple, Optional

# definition
class MyNamedTuple(NamedTuple):
    an_attribute: str
    my_attribute: Optional[str] = None
    next_attribute: int = 1

# instantiation
my_named_tuple = MyNamedTuple("abc", "def")
# or more explicitly:
other_tuple = MyNamedTuple(an_attribute="abc", my_attribute="def")

# access
assert "abc" == my_named_tuple.an_attribute
assert 1 == other_tuple.next_attribute