如何将元组转换为命名元组?

57

我希望在内部使用namedtuples,但我想保持与提供普通元组的用户的兼容性。

from collections import namedtuple

tuple_pi = (1, 3.14, "pi")  #Normal tuple 

Record = namedtuple("Record", ["ID", "Value", "Name"])

named_e = Record(2, 2.79, "e")  #Named tuple

named_pi = Record(tuple_pi)  #Error
TypeError: __new__() missing 2 required positional arguments: 'Value' and 'Name'

tuple_pi.__class__ = Record
TypeError: __class__ assignment: only for heap types
1个回答

82

您可以使用*args调用语法:

named_pi = Record(*tuple_pi)

这将把tuple_pi序列中的每个元素作为单独的参数传递。

你还可以使用namedtuple._make() 类方法将任何序列转换为实例:

named_pi = Record._make(tuple_pi)

示例:

>>> from collections import namedtuple
>>> Record = namedtuple("Record", ["ID", "Value", "Name"])
>>> tuple_pi = (1, 3.14, "pi")
>>> Record(*tuple_pi)
Record(ID=1, Value=3.14, Name='pi')
>>> Record._make(tuple_pi)
Record(ID=1, Value=3.14, Name='pi')

3
简短明了。我不明白你是如何如此迅速地回答问题的。 - Adam Ryczkowski
不错。您还可以使用关键字参数语法来传递一个字典:MyNamedTuple(**mydict)。当然,字典需要包含元组字段作为键。 - jurgispods
关于内存消耗:我可以在使用namedPi = Record(*tuplePi)或者namedPi = Record._make(tuplePi)转换后,摆脱tuplePi,对吗? - thinwybk
@thinwybk:是的,namedtuple实例现在引用了相同的值,所以你不再需要tuplePi了。 - Martijn Pieters
tuple.__new__(Record, tuple_pi)_make在幕后使用的工具 - ofo
@ofo:是的,因为Record.__new__本身就是一个薄薄的包装器,它包装了tuple.__new__(Record, ...)。重复使用相同的tuple_new引用比使用cls.__new__(cls, iterable)更简单、更高效,后者在调用tuple_new()之前会在解释器调用堆栈中创建一个新的函数框架。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接