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

阅读Python 3.1的变化,我发现了一些......意想不到的事情:

sys.version_info元组现在是一个命名元组

我以前从来没有听说过命名元组,并且我认为元素可以通过数字(如元组和列表)或按键(如在字典中)进行索引。 我从未想到他们可以通过两种方式进行索引。

因此,我的问题是:

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

  • 命名元组基本上是易于创建的轻量级对象类型。 命名的元组实例可以使用类似于对象的变量解引用或标准元组语法来引用。 它们可以类似地用于struct或其他常见记录类型,除非它们是不可变的。 它们是在Python 2.6和Python 3.0中添加的,尽管在Python 2.4中有一个实现的配方。

    例如,将一个点表示为一个元组(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}并且可以使用所有常用的字典功能进行操作。

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


    namedtuple是用于制作元组类的工厂函数 。 通过这个类,我们可以创建可以按名称调用的元组。

    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)
    

    namedtuples是一个很棒的功能,它们是数据的完美容器。 当你需要“存储”数据时,你会使用元组或字典,如:

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

    要么:

    user = ("John", 20)
    

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

    namedtuples是两种方法的完美折衷方案,具有很好的可读性,轻量级和不变性(加上它们是多态的!)。

    链接地址: http://www.djcxy.com/p/18019.html

    上一篇: What are "named tuples" in Python?

    下一篇: What is the most "pythonic" way to iterate over a list in chunks?