Bas Jansen
Bas Jansen

Reputation: 3343

Get the object name of a specific object from namedtuple

I have recently discovered namedtuple and want to use it to replace my icky large class definitions but I am curious if there is a smart way to retrieve the object's name of the value that I just selected, see the below example if it's unclear;

MyStruct = namedtuple("MyStruct","Var1 Var2 Var3")
Instance = MyStruct(1,2,3)
# What I currently do (but hopefully there is a smarter way to do this)
print "Var1:\t"+str(Instance.Var1)+"Var2:\t"+str(Instance.Var2) #and so forth

I know that there is the _fields option that would look something like this:

for x in Instance._fields:
  if str(x) == "Var1" or ... : # I only want to show certain objects at this time
    print x, getattr(Instance,x)

Still it looks rather un-pythonic to me, so is there a better way to do this?

Upvotes: 1

Views: 1598

Answers (2)

martineau
martineau

Reputation: 123473

namedtuplescan be indexed, so you don't need to turn one into a dict or use vars() to do what you want:

MyStruct = namedtuple("MyStruct","Var1 Var2 Var3")
instance = MyStruct(1, 2, 3)

fields_to_print = {'Var1', 'Var2'}
print(', '.join('{}: {}'.format(field, instance[i])
        for i, field in enumerate(instance._fields)
            if field in fields_to_print))

Output:

Var1: 1, Var2: 2

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1122152

A namedtuple instance has a namedtuple._asdict() method that returns an ordered dictionary:

>>> from collections import namedtuple
>>> MyStruct = namedtuple("MyStruct", "Var1 Var2 Var3")
>>> value = MyStruct('foo', 'bar', 'baz')
>>> value._asdict()
OrderedDict([('Var1', 'foo'), ('Var2', 'bar'), ('Var3', 'baz')])

This gives you an ordered dictionary with keys and values corresponding to the contents.

However, it is not clear to me what you are trying to achieve; what exactly is wrong with just selecting the right field directly?

print 'Var1: {}'.format(value.Var1)

or picking out specific fields with str.format():

print 'Var1: {0.Var1}, Var3: {0.Var3}'.format(value)

Upvotes: 1

Related Questions