I want to create a set of namedtuple in python, with the ability to add elements dynamically using the union operation.
The following code snippet creates a set of namedtuple, which is behaving nicely.
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 namedtuple and add it to my set with the union operations it is not behaving 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 output should be:
{B(name='b1', x=90), B(name='b2', x=92), B(name='b3', x=93)}
Am I mis-understanding the API? Both python2 and 3 are showing the same behaviour.
A namedtuple instance is an iterable of items. set.union simply merges the current set with the items in the namedtuple.
However, what you want is put the namedtuple in another container/iterable, so the merge is done with the item (the namedtuple) contained in the new parent iterable:
s.union((b3,))
It becomes more obvious if you actually think of the operator equivalent:
s = s | set(b3) # set(b3) -> {93, 'b3'}
As compared to what we actually want:
s = s | {b3}
The union is performed with the outer iterable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With