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

2024-12-18 08:39:00
admin
原创
138
摘要:问题描述:什么是命名元组以及如何使用它们?什么时候应该使用命名元组而不是普通元组,反之亦然?也有“命名列表”吗?(即可变命名元组)对于最后一个具体问题,另请参阅Python 中是否存在可变命名元组?。解决方案 1:命名元组基本上是一种易于创建的轻量级对象类型。可以使用类似对象的变量取消引用或标准元组语法来引用...

问题描述:

  • 什么是命名元组以及如何使用它们?

  • 什么时候应该使用命名元组而不是普通元组,反之亦然?

  • 也有“命名列表”吗?(即可变命名元组)


对于最后一个具体问题,另请参阅Python 中是否存在可变命名元组?。


解决方案 1:

命名元组基本上是一种易于创建的轻量级对象类型。可以使用类似对象的变量取消引用或标准元组语法来引用命名元组实例。它们的使用方式与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

因此,如果你认为对象表示法会使你的代码更符合 Python 风格且更易于阅读,那么你应该使用命名元组而不是元组。我个人已经开始使用它们来表示非常简单的值类型,特别是在将它们作为参数传递给函数时。它使函数更具可读性,而无需查看元组打包的上下​​文。

此外,你还可以用它们替换没有函数、只有字段的普通不可变类。你甚至可以使用命名元组类型作为基类:

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()返回值转换为字典{'x': 1.0, 'y': 5.0},并可以使用所有常用的字典函数对其进行操作。

正如前面提到的,您应该查看文档以获取构建这些示例的更多信息。

解决方案 2:

什么是命名元组?

命名元组是一个元组。

它可以完成元组所能做的一切。

但它不仅仅是一个元组。

它是根据您的规范以编程方式创建的元组的特定子类,具有命名字段和固定长度。

例如,这将创建元组的子类,除了长度固定(在本例中为 3)之外,它还可以用于使用元组的任何地方而不会中断。这称为里氏可替换性。

在 Python 3.6 中,我们可以使用类定义typing.NamedTuple来创建命名元组:

from typing import NamedTuple

class ANamedTuple(NamedTuple):
    """a docstring"""
    foo: int
    bar: str
    baz: list

上面的代码与 相同collections.namedtuple,只是上面的代码还带有类型注释和文档字符串。下面的代码在 Python 2+ 中可用:

>>> from collections import namedtuple
>>> class_name = 'ANamedTuple'
>>> fields = 'foo bar baz'
>>> ANamedTuple = namedtuple(class_name, fields)

以下实例化它:

>>> ant = ANamedTuple(1, 'bar', [])

我们可以检查它并使用它的特性:

>>> ant
ANamedTuple(foo=1, bar='bar', baz=[])
>>> ant.foo
1
>>> ant.bar
'bar'
>>> ant.baz.append('anything')
>>> ant.baz
['anything']

更深层次的解释

要理解命名元组,首先需要知道什么是元组。元组本质上是一个不可变(无法在内存中就地更改)列表。

使用常规元组的方法如下:

>>> student_tuple = 'Lisa', 'Simpson', 'A'
>>> student_tuple
('Lisa', 'Simpson', 'A')
>>> student_tuple[0]
'Lisa'
>>> student_tuple[1]
'Simpson'
>>> student_tuple[2]
'A'

您可以使用可迭代解包来扩展元组:

>>> first, last, grade = student_tuple
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'

命名元组是允许通过名称而不是仅通过索引来访问其元素的元组!

你可以像这样创建一个命名元组:

>>> from collections import namedtuple
>>> Student = namedtuple('Student', ['first', 'last', 'grade'])

您还可以使用以空格分隔的名称的单个字符串,这是一种更易读的 API 用法:

>>> Student = namedtuple('Student', 'first last grade')

如何使用它们?

你可以做元组能做的所有事情(见上文)以及执行以下操作:

>>> named_student_tuple = Student('Lisa', 'Simpson', 'A')
>>> named_student_tuple.first
'Lisa'
>>> named_student_tuple.last
'Simpson'
>>> named_student_tuple.grade
'A'
>>> named_student_tuple._asdict()
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> vars(named_student_tuple)
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> new_named_student_tuple = named_student_tuple._replace(first='Bart', grade='C')
>>> new_named_student_tuple
Student(first='Bart', last='Simpson', grade='C')

有评论者问道:

在大型脚本或程序中,通常在哪里定义命名元组?

您创建的类型namedtuple基本上是可以用简单的简写创建的类。将它们视为类。在模块级别定义它们,以便 pickle 和其他用户可以找到它们。

全局模块级别的工作示例:

>>> from collections import namedtuple
>>> NT = namedtuple('NT', 'foo bar')
>>> nt = NT('foo', 'bar')
>>> import pickle
>>> pickle.loads(pickle.dumps(nt))
NT(foo='foo', bar='bar')

这表明查找定义失败:

>>> def foo():
...     LocalNT = namedtuple('LocalNT', 'foo bar')
...     return LocalNT('foo', 'bar')
... 
>>> pickle.loads(pickle.dumps(foo()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class '__main__.LocalNT'>: attribute lookup LocalNT on __main__ failed

为什么/何时应该使用命名元组而不是普通元组?

当它可以改进你的代码以在代码中表达元组元素的语义时使用它们。

如果您要使用具有不变的数据属性且没有任何功能的对象,那么您可以使用它们来代替对象。

您还可以对它们进行子类化以添加功能,例如:

class Point(namedtuple('Point', 'x y')):
    """adding functionality to a named tuple"""
        __slots__ = ()
        @property
        def hypot(self):
            return (self.x ** 2 + self.y ** 2) ** 0.5
        def __str__(self):
            return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

为什么/何时应该使用普通元组而不是命名元组?

从使用命名元组切换到元组可能是一种倒退。前期设计决策的核心在于,当使用元组时,所涉及的额外代码的成本是否值得提高可读性。

与元组相比,命名元组并不占用额外的内存。

是否存在任何类型的“命名列表”(命名元组的可变版本)?

您正在寻找一个可以实现静态大小列表的所有功能的插槽对象,或者一个像命名元组一样工作的子类列表(并且以某种方式阻止列表大小发生变化)。

第一个例子现已扩展,甚至可能可以用 Liskov 替代:

from collections import Sequence

class MutableTuple(Sequence): 
    """Abstract Base Class for objects that work like mutable
    namedtuples. Subclass and define your named fields with 
    __slots__ and away you go.
    """
    __slots__ = ()
    def __init__(self, *args):
        for slot, arg in zip(self.__slots__, args):
            setattr(self, slot, arg)
    def __repr__(self):
        return type(self).__name__ + repr(tuple(self))
    # more direct __iter__ than Sequence's
    def __iter__(self): 
        for name in self.__slots__:
            yield getattr(self, name)
    # Sequence requires __getitem__ & __len__:
    def __getitem__(self, index):
        return getattr(self, self.__slots__[index])
    def __len__(self):
        return len(self.__slots__)

要使用,只需子类化并定义__slots__

class Student(MutableTuple):
    __slots__ = 'first', 'last', 'grade' # customize 


>>> student = Student('Lisa', 'Simpson', 'A')
>>> student
Student('Lisa', 'Simpson', 'A')
>>> first, last, grade = student
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'
>>> student[0]
'Lisa'
>>> student[2]
'A'
>>> len(student)
3
>>> 'Lisa' in student
True
>>> 'Bart' in student
False
>>> student.first = 'Bart'
>>> for i in student: print(i)
... 
Bart
Simpson
A

解决方案 3:

namedtuple是用于创建元组类的工厂函数。通过该类,我们还可以创建可通过名称调用的元组。

import collections

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

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)

解决方案 4:

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

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

或者:

user = ("John", 20)

字典方法不尽人意,因为字典是可变的,比元组慢。另一方面,元组是不可变的,而且很轻量,但对于数据字段中的大量条目来说,缺乏可读性。

namedtuples 是两种方法的完美折衷,具有很强的可读性、轻量性和不变性(而且它们是多态的!)。

解决方案 5:

命名元组允许向后兼容,代码会检查版本,如下所示

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

同时允许将来的代码通过使用此语法更加明确

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

解决方案 6:

命名元组

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

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"

第一个例子中发生的事情很难理解。使用命名元组,每个字段都有一个名称。并且您可以通过名称而不是位置或索引来访问它。p[1]我们可以将其称为 p.saturation,而不是 。这更容易理解。而且看起来更简洁。

创建 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

  1. 正如刚才所说,namedtuple 使元组的理解变得更容易。因此,如果您需要引用元组中的项目,那么将它们创建为 namedtuple 是合理的。

  2. namedtuple 除了比字典更轻量之外,还与字典不同地保持顺序。

  3. 如上例所示,创建命名元组实例比创建字典实例更简单。并且引用命名元组中的项目看起来比字典更简洁。p.hue而不是
    p['hue']

语法

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
  • namedtuple 在集合库中。

  • typename:这是新元组子类的名称。

  • field_names:每个字段的名称序列。它可以是列表['x', 'y', 'z']或字符串中的序列x y z(没有逗号,只有空格)或x, y, z

  • rename:如果 rename 为True,则无效的字段名将自动替换为位置名称。例如,['abc', 'def', 'ghi','abc']转换为['abc', '_1', 'ghi', '_3'],消除关键字'def'(因为这是定义函数的保留字)和重复的字段名'abc'

  • 详细:如果详细True,则在构建之前打印类定义。

如果您愿意,您仍然可以通过其位置访问命名元组。p[1] == p.saturation它仍然像常规元组一样解包。

方法

支持所有常规元组方法。例如:min()、max()、len()、in、not in、连接 (+)、索引、切片等。此外,还支持一些用于命名元组的其他方法。注意:这些方法都以下划线开头。_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生成一个new实例;它不会修改原始值或替换旧值。当然,您可以将新结果保存到变量中。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

解决方案 7:

from collections import namedtuple 
  • 它们将元组子类化,并添加一个层来为位置元素分配属性名称

'namedtuple' 是一个函数,它生成一个从“tuple”继承的新类,但也提供“命名属性”来访问元组的元素。

生成命名元组类

“namedtuple” 是一个类工厂。它需要一些东西来生成类

  • 班级名称

  • 我们要分配的字段名称序列,按照元组中元素的顺序排列。字段名称可以是任何有效的变量名称,但不能以“下划线”开头。

  • 调用“namedtuple”的返回值将是一个类。我们需要在代码中将该类分配给一个变量名,以便使用它来构造实例。一般来说,我们使用与生成的类相同的名称。

# Coords is a class
Coords = namedtuple('Coords', ['x', 'y'])
  • 现在我们可以创建 Coords 类的实例:

pt=Coords(10,20)
  • 我们可以通过多种方式向 namedtuple 函数提供字段名称列表。

+ 字符串列表


 namedtuple('Coords', ['x','y'])
+ 字符串元组


 namedtuple('Coords', ('x','y'))
+ 单个字符串,字段名称以空格或逗号分隔


 namedtuple('Coords', 'x, y')

实例化命名元组

当我们创建了命名元组类之后,我们就可以像普通类一样实例化它们。实际上,__new__生成的类的方法使用我们提供的字段名称作为参数名称。

Coords = namedtuple('Coords', ['x', 'y'])
coord=Coords(10,20) 

访问命名元组中的数据:

由于命名元组继承自元组,我们仍然可以像处理其他元组一样处理它们:通过索引、切片、迭代

Coords = namedtuple('Coords', ['x', 'y'])
coord=Coords(10,20)       isinstance(coord,tuple) --> True # namedtuple is subclass of tuple

x,y=coord  # Unpacking
x=coord[0] # by index
for e in coord:
    print(e)
  • 现在我们也可以像访问类一样使用字段名称访问数据。

coord.x --> 10
coord.y --> 20
  • 由于namedtuple是从tuple继承的生成类,因此我们可以这样写:

class Coord(tuple):
    ....
  • “coord” 是一个元组,因此不可变

namedtuple 的“rename”关键字参数

字段名称不能以下划线开头

Coords = namedtuple('Coords', ['x', '_y']) # does not work

namedtuple 有一个仅关键字参数rename(默认为 False),它将自动重命名任何无效的字段名称。

Coords = namedtuple('Coords', ['x', '_y'], rename=True)

字段名称“x”不会改变,但“_y”会改变_1。1是字段名称的索引。

想象一下这样的场景:您需要更新应用程序,因此想要使用 namedtuple 来存储应用程序的用户。您需要提取列名,但它们对于命名元组无效,并且会引发异常。在这种情况下,您可以使用rename=True

将命名元组值提取到字典中

Coords = namedtuple('Coords', ['x', 'y'])
coord=Coords(10,20)
coord._asdict()
   {'x': 10, 'y': 20}

为什么要使用 namedtuple

如果你有这个课程:

class Stock:
    def __init__(self, symbol, year, month, day, open, high, low, close):
        self.symbol = symbol
        self.year = year
        self.month = month
        self.day = day
        self.open = open 
        self.high = high
        self.low = low
        self.close = close

类方法元组方法

stock.symbol              stock[0]     
stock.open                stock[4]
stock.close               stock[7]
stock.high – stock.low    stock[5] – stock[6]

如您所见,元组方法不可读。collectionsnamedtuple 中的函数允许我们创建一个元组,该元组还为每个字段或属性附加了名称。这可以方便地通过“名称”引用元组结构中的数据,而不仅仅是依靠位置。但请记住,元组是不可变的,因此如果您想要可变性,请坚持使用类

  • 由于 namedtuple 是可迭代的,因此您可以使用可迭代方法。例如,如果您有“coords”作为类实例,则无法查找最大 coord 是多少。但使用 named-tuple,您可以。

解决方案 8:

什么是 namedtuple?

顾名思义,namedtuple 是一个带有名称的元组。在标准元组中,我们使用索引访问元素,而 namedtuple 允许用户为元素定义名称。这非常方便,尤其是在处理 csv(逗号分隔值)文件和处理复杂且大型的数据集时,使用索引会使代码变得混乱(不太符合 Python 风格)。

如何使用它们?

>>>from collections import namedtuple
>>>saleRecord = namedtuple('saleRecord','shopId saleDate salesAmout totalCustomers')
>>>
>>>
>>>#Assign values to a named tuple 
>>>shop11=saleRecord(11,'2015-01-01',2300,150) 
>>>shop12=saleRecord(shopId=22,saleDate="2015-01-01",saleAmout=1512,totalCustomers=125)

阅读

>>>#Reading as a namedtuple
>>>print("Shop Id =",shop12.shopId)
12
>>>print("Sale Date=",shop12.saleDate)
2015-01-01
>>>print("Sales Amount =",shop12.salesAmount)
1512
>>>print("Total Customers =",shop12.totalCustomers)
125

CSV 处理中的有趣场景:

from csv import reader
from collections import namedtuple

saleRecord = namedtuple('saleRecord','shopId saleDate totalSales totalCustomers')
fileHandle = open("salesRecord.csv","r")
csvFieldsList=csv.reader(fileHandle)
for fieldsList in csvFieldsList:
    shopRec = saleRecord._make(fieldsList)
    overAllSales += shopRec.totalSales;

print("Total Sales of The Retail Chain =",overAllSales)

解决方案 9:

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

使用命名元组将会直接应用默认的类模板来生成一个简单的类,这种方法可以让大量的代码提高可读性并且在定义类的时候也很方便。

解决方案 10:

我认为值得使用类型提示添加有关 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

解决方案 11:

使用命名元组的另一种方法(一种新方法)是使用来自 typing 包的 NamedTuple:namedtuple 中的类型提示

让我们使用这篇文章中最佳答案的示例来看看如何使用它。

(1)在使用命名元组之前,代码是这样的:

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)
print(line_length)

(2)现在我们使用命名元组

from typing import NamedTuple

继承NamedTuple类,在新类中定义变量名,test是类名。

class test(NamedTuple):
    x: float
    y: float

从类创建实例并为其分配值

pt1 = test(1.0, 5.0)   # x is 1.0, and y is 5.0. The order matters
pt2 = test(2.5, 1.5)

使用实例中的变量来计算

line_length = sqrt((pt1.x - pt2.x)**2 + (pt1.y - pt2.y)**2)
print(line_length)

解决方案 12:

尝试一下:

collections.namedtuple()

基本上,namedtuples是易于创建的轻量级对象类型。它们将元组转换为简单任务的便捷容器。使用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

解决方案 13:

命名元组的文档可在此处找到:
https ://docs.python.org/3/library/collections.html#collections.namedtuple

以下是示例代码,显示了脚本,尽管它更冗长,但更易于阅读,可以区分命名元组中的哪个字段。在普通元组中,可以使用索引来检索第 n 个字段(从 0 开始)。但对于命名元组,可以使用字段名称。

from collections import namedtuple

Customer = namedtuple('Customer', ['Name', 'Age', 'Height'])
 
customers2 =  [
    Customer(Name = 'Jenna', Age = 42, Height = 165),
    Customer(Name = 'Thor', Age = 38, Height = 174),
    Customer(Name = 'Christopher', Age = 42, Height = 170),
    Customer(Name = 'Liz', Age = 42, Height = 168),
 ]
   
for cust in customers2:
    print(f"{cust.Name} with a height of {cust.Height}(cm)")

输出:

Jenna with a height of 165(cm)
Thor with a height of 174(cm)
Christopher with a height of 170(cm)
Liz with a height of 168(cm)

当你的元组包含许多字段时,这种可读性应该可以减少错误。此外,如果你向元组添加更多字段,则不必在脚本中修复索引。因此,代码会更冗长一些,但也更易于更改且更易读。

解决方案 14:

其他人都已经回答了,但我想我还有一些要补充的。

Namedtuple 可以直观地看作是定义类的快捷方式。

了解定义 的繁琐且常规的方法class

class Duck:
    def __init__(self, color, weight):
        self.color = color
        self.weight = weight
red_duck = Duck('red', '10')

    In [50]: red_duck
    Out[50]: <__main__.Duck at 0x1068e4e10>
    In [51]: red_duck.color
    Out[51]: 'red'

至于namedtuple

from collections import namedtuple
Duck = namedtuple('Duck', ['color', 'weight'])
red_duck = Duck('red', '10')

In [54]: red_duck
Out[54]: Duck(color='red', weight='10')
In [55]: red_duck.color
Out[55]: 'red'
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用