Python collection join operation doesn't behave well with named tuples

I want to create a collection namedtuplein python, with the ability to dynamically add elements using a join operation.

The following code snippet creates setfrom namedtuplewhich behaves beautifully.

from collections import namedtuple

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

b1 = B('b1',90)
b2 = B('b2',92)
s = set([b1,b2])
print(s)

which prints

{B(name='b1', x=90), B(name='b2', x=92)}

Now, if I create another one namedtupleand add it to mine setusing operations union, it will not behave as expected.

b3 = B('b3',93)
s = s.union(b3)
print(s)

The code snippet prints the following output.

{93, B(name='b1', x=90), B(name='b2', x=92), 'b3'}

The expected result should be:

{B(name='b1', x=90), B(name='b2', x=92), B(name='b3', x=93)}

Am I misunderstanding the API? Both python2 and 3 show the same behavior.

+4
source share
4

union ( ), , , , . :

s = s.union({b3})
+1

A namedtuple instance - . set.union namedtuple.

namedtuple /, (namedtuple), :

s.union((b3,))

, :

s = s | set(b3) # set(b3) -> {93, 'b3'}

, :

s = s | {b3}

.

+3

b3 , union , . :

s = s.union([b3])
+1

The documentation set.uniondoes indeed explain this:

union(*others)

Returns a new set with elements from the set and all the others.

Thus, he will create a new set including all elements from others:

>>> set(b3)  # these are the unique elements in your `b3`
{93, 'b3'}

>>> s.union(b3)   # the union of the unique elements in "s" and "b3"
{B(name='b1', x=90), 93, 'b3', B(name='b2', x=92)}

In your case (since you assign it back to s), you can simply add an element, thereby avoiding creating the whole set:

>>> s.add(b3)
>>> s
{B(name='b1', x=90), B(name='b3', x=93), B(name='b2', x=92)}
0
source

Source: https://habr.com/ru/post/1684757/


All Articles