how do I add fields to a namedtuple?
Solution 1
Notice that here you're modifying the type
of the named tuples, not instances of that type. In this case, you'd probably want to create a new type with an additional field from the old one:
result = namedtuple('Result',result._fields+('point',))
e.g.:
>>> result = namedtuple('Result',['x','y'])
>>> result = namedtuple('Result',result._fields+('point',))
>>> result._fields
('x', 'y', 'point')
Solution 2
You can easily concatenate namedtuples, keeping in mind that they are immutable
from collections import namedtuple
T1 = namedtuple('T1', 'a,b')
T2 = namedtuple('T2', 'c,d')
t1 = T1(1,2)
t2 = T2(3,4)
def sum_nt_classes(*args):
return namedtuple('_', ' '.join(sum(map(lambda t:t._fields, args), ())))
def sum_nt_instances(*args):
return sum_nt_classes(*args)(*sum(args,()))
print sum_nt_classes(T1,T2)(5,6,7,8)
print sum_nt_instances(t1,t2)
Solution 3
You cannot add a new field to a namedtuple
after defining it. Only way is to create a new template and creating new namedtuple
instances.
Analysis
>>> from collections import namedtuple
>>> result = namedtuple('Result',['x','y'])
>>> result
<class '__main__.Result'>
result
is not a tuple, but the class which creates tuples.
>>> result.x
<property object at 0x02B942A0>
You create a new tuple like this:
>>> p = result(1, 2)
>>> p
Result(x=1, y=2)
>>> p.x
1
Prints the value x
in p
.
>>> p.x = 5
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
p.x = 5
AttributeError: can't set attribute
This throws error because tuple is immutable.
>>> result.x = 5
>>> result
<class '__main__.Result'>
>>> result._fields
('x', 'y')
>>> p = result(1, 2)
>>> p
Result(x=1, y=2)
This doesn't change anything.
>>> result.description = 'point'
>>> result
<class '__main__.Result'>
>>> result._fields
('x', 'y')
This doesn't change anything either.
Solution
>>> result = namedtuple('Result', ['x','y'])
>>> p = result(1, 2)
>>> p
Result(x=1, y=2)
>>> # I need one more field
>>> result = namedtuple('Result',['x','y','z'])
>>> p1 = result(1, 2, 3)
>>> p1
Result(x=1, y=2, z=3)
>>> p
Result(x=1, y=2)
rudivonstaden
Updated on July 17, 2022Comments
-
rudivonstaden almost 2 years
I am working with a list of namedtuples. I would like to add a field to each named tuple after it has already been created. It seems I can do that by just referencing it as an attribute (as in
namedtuple.attribute = 'foo'
), but then it isn't added to the list of fields. Is there any reason why I shouldn't do it this way if I don't do anything with the fields list? Is there a better way to add a field?>>> from collections import namedtuple >>> result = namedtuple('Result',['x','y']) >>> result.x = 5 >>> result.y = 6 >>> (result.x, result.y) (5, 6) >>> result.description = 'point' >>> (result.x, result.y, result.description) (5, 6, 'point') >>> result._fields ('x', 'y')