I have a list of dictionaries and I'd like to retrieve their name from a loop like :
for d in list_dicts:
print d.name
list_dicts = [dic1, dic2]
d.name = dic1
Is it possible and how ? Thank you
I have a list of dictionaries and I'd like to retrieve their name from a loop like :
for d in list_dicts:
print d.name
list_dicts = [dic1, dic2]
d.name = dic1
Is it possible and how ? Thank you
dic1
or dic2
are variable names. They mean nothing. In fact, you can do:
dic1 = {1:2, 3:4}
dic2 = dic1
list_dicts = [dic1, dic2]
And here the list contains two references to the same dictionary!
If you really need a name, you can either simply add it to the dictionary (kinda hacky, but should work as long as the key is unique):
dic1['name'] = 'dic1'
You could wrap them both in a class:
class NamedDct(object):
def __init__(self, dct, name):
self.dct = dct
self.name = name
dic1 = NamedDct(dic1, 'dic1')
Or you could inherit from dict (please note that this is a degenerate example, not diving into the details):
class NamedDct(dict):
def __init__(self, name):
self.name = name
super(NamedDct, self).__init__()
dic1_new = NamedDct('dic1')
dic1_new.update(dic1)
You may want to use a namedtuple for something like this.
Named tuples allow the construction of a lightweight name / data combination (in the form of a Python subclass of a tuple) that is perfect for this use case.
Suppose we want a dict that is attached to a name.
(With verbose=True
the entire class is printed out for inspection. In normal use, do not include that...)
>>> from collections import namedtuple
>>> NamedDict = namedtuple('NamedDict', 'name data', verbose=True)
class NamedDict(tuple):
'NamedDict(name, data)'
__slots__ = ()
_fields = ('name', 'data')
def __new__(_cls, name, data):
'Create new instance of NamedDict(name, data)'
return _tuple.__new__(_cls, (name, data))
@classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
'Make a new NamedDict object from a sequence or iterable'
result = new(cls, iterable)
if len(result) != 2:
raise TypeError('Expected 2 arguments, got %d' % len(result))
return result
def __repr__(self):
'Return a nicely formatted representation string'
return 'NamedDict(name=%r, data=%r)' % self
def _asdict(self):
'Return a new OrderedDict which maps field names to their values'
return OrderedDict(zip(self._fields, self))
def _replace(_self, **kwds):
'Return a new NamedDict object replacing specified fields with new values'
result = _self._make(map(kwds.pop, ('name', 'data'), _self))
if kwds:
raise ValueError('Got unexpected field names: %r' % kwds.keys())
return result
def __getnewargs__(self):
'Return self as a plain tuple. Used by copy and pickle.'
return tuple(self)
__dict__ = _property(_asdict)
def __getstate__(self):
'Exclude the OrderedDict from pickling'
pass
name = _property(_itemgetter(0), doc='Alias for field number 0')
data = _property(_itemgetter(1), doc='Alias for field number 1')
Consider
>>> nd=NamedDict('dict1', {1:'one', 2:'two'})
>>> nd
NamedDict(name='dict1', data={1: 'one', 2: 'two'})
>>> nd.name
'dict1'
>>> nd.data
{1: 'one', 2: 'two'}
So you can then associate a name and dict with each pair in a list:
LoT=[
('dict1', {1:'one', 2:'two'}),
('dict2', {3:'three', 4:'four'})
]
NamedDict = namedtuple('NamedDict', 'name data')
LoND=[NamedDict(*t) for t in LoT]
for d in LoND:
print(d.name, d.data)
Prints:
dict1 {1: 'one', 2: 'two'}
dict2 {3: 'three', 4: 'four'}
Supposing you have a list with dictionaries like this:
dic1: {"name": "Name1", ...} dic2: {"name": "Name2", ...}
And a list like this: list_dicts = [dic1, dic2]
The way to access dictionary fields are literal notation (with brackets).
for d in list_dicts:
print d["name"]