Python: Copying named tuples with same attributes / fields
Asked Answered
D

2

12

I am writing a function that takes a named tuple and must return a super set of that tuple.

For example if I was to receive a named tuple like this:

Person(name='Bob', age=30, gender='male')

I want to return a tuple that looks like this:

Person(name='Bob', age=30, gender='male', x=0)

Currently I am doing this:

tuple_fields = other_tuple[0]._fields
tuple_fields = tuple_fields + ('x')
new_tuple = namedtuple('new_tuple', tuple_fields)

Which is fine, but I do not want to have to copy each field like this:

tuple = new_tuple(name=other_tuple.name, 
                  age=other_tuple.age, 
                  gender=other_tuple.gender, 
                  x=0)

I would like to be able to just iterate through each object in the FIRST object and copy those over. My actual tuple is 30 fields.

Departed answered 5/12, 2016 at 18:19 Comment(1)
Possible duplicate of Inherit namedtuple from a base class in pythonCinderellacindi
C
20

You could try utilizing dict unpacking to make it shorter, eg:

tuple = new_tuple(x=0, **other_tuple._asdict())
Carlin answered 5/12, 2016 at 18:34 Comment(3)
Whether namedtuples have a __dict__ and how it works is rather inconsistent across Python versions. I don't think the latest 3.5 revision has it. Having a __dict__ for namedtuples was a bad idea in the first place, and it caused some nasty bugs.Onepiece
If you want a dict representation of a namedtuple, there's the _asdict method.Onepiece
@Onepiece Thanks, I'll update my answer for that. __dict__ worked fine for me, but I'm stuck on Python 3.4.Carlin
N
2

The accepted version is broken, you will get a new_tuple() got multiple values for argument 'x' error.

You should use _replace instead:

https://docs.python.org/3/library/collections.html#collections.somenamedtuple._replace

Noctambulous answered 19/12, 2023 at 6:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.