python set union 操作对于命名元组表现不佳

bru*_*yne 4 python set namedtuple python-collections

我想在 python 中创建一组namedtuple,能够使用联合操作动态添加元素。

下面的代码片段创建了一个setof namedtuple,它表现得很好。

from collections import namedtuple

B = namedtuple('B', 'name x')

b1 = B('b1',90)
b2 = B('b2',92)
s = set([b1,b2])
print(s)
Run Code Online (Sandbox Code Playgroud)

打印

{B(name='b1', x=90), B(name='b2', x=92)}
Run Code Online (Sandbox Code Playgroud)

现在,如果我创建另一个namedtuple并将其添加到我的操作setunion,它的行为将不会按预期进行。

b3 = B('b3',93)
s = s.union(b3)
print(s)
Run Code Online (Sandbox Code Playgroud)

该代码片段打印以下输出。

{93, B(name='b1', x=90), B(name='b2', x=92), 'b3'}
Run Code Online (Sandbox Code Playgroud)

预期输出应该是:

{B(name='b1', x=90), B(name='b2', x=92), B(name='b3', x=93)}
Run Code Online (Sandbox Code Playgroud)

我是不是对API理解有误?python2 和 3 都显示出相同的行为。

Mos*_*oye 5

实例namedtuple是项目的可迭代对象。set.union只是将当前集合与 中的项目合并namedtuple

\n\n

但是,您想要的是将 放入另一个容器/可迭代对象中,以便与新父可迭代对象中包含的namedtuple项目( )完成合并:namedtuple

\n\n
s.union((b3,))\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果你真正考虑等价的运算符,它会变得更加明显:

\n\n
s = s | set(b3) #\xc2\xa0set(b3) -> {93, 'b3'}\n
Run Code Online (Sandbox Code Playgroud)\n\n

与我们实际想要的相比:

\n\n
s = s | {b3}\n
Run Code Online (Sandbox Code Playgroud)\n\n

联合是与外部可迭代执行的

\n