Reputation: 23
this is my first question on stackoverflow. I just learnt the namedtuple and found sth weird.
When you want to initiate a namedtuple from an iterable, you have to either add a prefix * or use the _make method.
for instance:
City=namedtuple('city',['name','country','population','coordinates'])
delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))
delhi = City(*('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889)))
But when you initiate a tuple, dict or even orderedDict from the same collection package, you can just tuple() or dict() or orderedDict().
for instance:
from collections import OrderedDict
items = (
('A', 1),
('B', 2),
('C', 3)
)
regular_dict = dict(items)
ordered_dict = OrderedDict(items)
Why the syntax for namedtuple is so weird? Thanks!
Upvotes: 1
Views: 529
Reputation: 251458
You can see some discussion here about why namedtuple was designed this way. The basic reason is that the "normal" way to create a namedtuple is with a call like MyTupleClass(1, 2, 3)
, where the values are accepted as separate arguments. If it accepted only one iterable argument (as tuple
does), you would have to write MyTupleClass((1, 2, 3))
with an extra set of parentheses (that is, MyTupleClass(1, 2, 3)
would raise an error, as tuple(1, 2, 3)
does). It is true that this means you have to use an extra star (or use the ._make()
method) if initializing from an iterable, but this isn't any harder, it's just different. The decision was apparently to make the simple case (initializing with literal values) easier, at the expense of making a more complex case (unpacking from an iterable) a bit different from a regular tuple.
Upvotes: 2
Reputation: 49812
From your example, it behaves similarly to a dict:
from collections import namedtuple
MyTuple = namedtuple('MyTuple', 'A B C')
items = (('A', 1), ('B', 2), ('C', 3))
my_tuple = MyTuple(**dict(items))
Upvotes: 1