jijijude
jijijude

Reputation: 23

namedtuple in python syntax weird from built-in types and orderedDict

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

Answers (2)

BrenBarn
BrenBarn

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

Stephen Rauch
Stephen Rauch

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

Related Questions