在 Python 中合并命名元组的简单方法是啥?

Posted

技术标签:

【中文标题】在 Python 中合并命名元组的简单方法是啥?【英文标题】:What is the simple way to merge named tuples in Python?在 Python 中合并命名元组的简单方法是什么? 【发布时间】:2012-08-23 02:26:58 【问题描述】:

我想在不丢失键名的情况下合并两个命名元组。如果,我只是与 '+' 运算符合并,我得到一个元组,但没有名称。

例如:

n [1]: from collections import namedtuple

In [2]: A = namedtuple("A", "a b c")

In [4]: B = namedtuple("B", "d e")

In [5]: a = A(10, 20, 30)

In [6]: b = B(40, 50)

In [7]: a + b
Out[7]: (10, 20, 30, 40, 50)

正如您在上面的例子中看到的,a + b 的结果没有与之关联的名称。

但是,我可以通过创建第三个命名元组来实现它,它具有来自 A 和 B 的字段。

In [8]: C = namedtuple("C", A._fields + B._fields)

In [9]: C(*(a + b))
Out[9]: C(a=10, b=20, c=30, d=40, e=50)

这是正确的方法还是有更好的方法?

【问题讨论】:

您可以使用字典和.update() 方法或 k:v for d in (a,b) for k,v in d.items() 技巧。 namedtuple 是关于定义一组固定的属性,你似乎违反了。 一个更好的问题是你为什么需要这个。 @delnan 我需要这个,因为我正在尝试加入两个命名元组列表。我想这是一个相当正常的用例。 @Senthil:不,这不是一个正常的用例。通常,您使用namedtuple 构造函数定义一些“类型”,然后创建它的实例。这有点像 C 语言中的struct。我认为你想使用字典 【参考方案1】:

就 vanilla Python 而言,您几乎已经掌握了它,但如果您使用的是 Python 3.5+,则可以进行额外的简化。

>>> from collections import namedtuple
>>> A = namedtuple("A", "a b c")
>>> B = namedtuple("B", "d e")
>>> a = A(10, 20, 30)
>>> b = B(40, 50)
>>> C = namedtuple("C", A._fields + B._fields)
>>> C(*(a + b))
C(a=10, b=20, c=30, d=40, e=50)
>>> #Available in Python 3.5+
>>> C(*a, *b)
C(a=10, b=20, c=30, d=40, e=50)

此外,如果您发现自己经常这样做,可以使用以下函数来消除样板代码:

>>> from functools import reduce
>>> from itertools import chain
>>> from operator import add
>>> def namedtuplemerge(*args):
...     cls = namedtuple('_'.join(arg.__class__.__name__ for arg in args), reduce(add, (arg._fields for arg in args)))
...     return cls(*chain(*args))
...
>>> namedtuplemerge(a, b)
A_B(a=10, b=20, c=30, d=40, e=50)

【讨论】:

【参考方案2】:

怎么样

>>> [a] + [b]
[A(a=10, b=20, c=30), B(d=40, e=50)]

【讨论】:

【参考方案3】:

Python 不会自动创建一个新的namedtuple,一个新的类。您必须自己定义组合的namedtuple

A = namedtuple("A", "a b c")
B = namedtuple("B", "d e")
AB = namedtuple("AB", "a b c d e")

a = A(1,2,3)
b = B(4,5)
ab = AB(*(a+b))

>>> a
A(a=1, b=2, c=3)
>>> b
B(d=4, e=5)
>>> ab
AB(a=1, b=2, c=3, d=4, e=5)

【讨论】:

【参考方案4】:

一些观察:

通常,当您尝试合并两个恰好具有相同名称的字段的命名元组时,Python 不知道该怎么做。也许这就是为什么没有运算符或函数的原因。

documentation of _fields 说:

列出字段名称的字符串元组。对于自省和从现有命名元组创建新的命名元组类型很有用。

这表明您的方法很好,甚至可能由 namedtuple 代码的作者暗示。

【讨论】:

以上是关于在 Python 中合并命名元组的简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在python中循环命名元组的元素

命名元组内命名元组的 Python 语法

Python:扁平化包含来自函数的另一个元组的元组的最简单方法

Python中的“命名元组”是啥?

Python中的“命名元组”是啥?

Python基础入门之数据结构简汇