0

Below is how I create and use a namedtuple object:

>>> from collections import namedtuple
>>> labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
>>> data = namedtuple('data', labels)
>>> my_data1 = data(a=0, b=1, c=2, d=3, e=4, f=5, g=6, h=7, i=8, j=9)
>>> my_data1
data(a=0, b=1, c=2, d=3, e=4, f=5, g=6, h=7, i=8, j=9)

Instead of having to manually type this multiple times:

my_data1 = data(a=0, b=1, c=2, d=3, e=4, f=5, g=6, h=7, i=8, j=9)

How do I write a for-loop or use a comprehension approach to write this? E.g. if values is a list object, e.g. list(range(10)) or a list of any values, how do I create a new instance of data with a for-loop and different list of values?

Sun Bear
  • 7,594
  • 11
  • 56
  • 102
  • 1
    `data(*range(10)) -> data(a=0, b=1, c=2, d=3, e=4, f=5, g=6, h=7, i=8, j=9)`? – Ch3steR Dec 08 '21 at 17:05
  • 2
    Does this answer your question? [Python unpacking operator (\*)](https://stackoverflow.com/questions/50950690/python-unpacking-operator) – Peter Badida Dec 08 '21 at 17:06
  • @SunBear Number of labels are 10 and `range(10, 19, 1)` is 9 elements. So, your `j` did not get any value. Hence, the error. – Ch3steR Dec 08 '21 at 17:15
  • @Ch3steR I noticed. Hence, I deleted my comment. Your answer is correct. Pls write it up and I accept it. – Sun Bear Dec 08 '21 at 17:21

2 Answers2

0

You can zip() the labels and values into a tuple list, then dict() it and pass to your data() constructor as keyword arguments:

labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
values = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
kwargs = dict(zip(labels, values)))
my_data1 = data(**kwargs))
vaizki
  • 1,678
  • 1
  • 9
  • 12
  • The answer in the comment of @Ch3steR and PeterBadida is correct. Your answer is incorrect although it might work. – Sun Bear Dec 08 '21 at 17:21
  • My answer works for a different list of values (as requested) and most closely resembles the way you called the `data()` constructor before so how is it incorrect? – vaizki Dec 08 '21 at 17:36
0

If you want a one-liner you can do something like this:

from inspect import signature
my_data1 = data(**{i: j for i, j in zip(signature(data).parameters, range(10))})

This basically gets the parameters of the namedtuple and gets the numbers 0-9 and zips them together. With some dictionary comprehension magic I created a dictionary with the keys being the parameters of the named tuple and the values being the actual values (the numbers). At the end I unpacked the dictionary and put everything inside of the data namedtuple.

CozyCode
  • 484
  • 4
  • 13