I find myself needing to iterate over a list made of dictionaries and I need, for every iteration, the name of which dictionary I\'m iterating on.
Here\'s an MWE (the co
The following doesn't work on standard dictionaries, but does work just fine with collections dictionaries and counters:
from collections import Counter
# instantiate Counter ditionary
test= Counter()
# create an empty name attribute field
test.name = lambda: None
# set the "name" attribute field to "name" = "test"
setattr(test.name, 'name', 'test')
# access the nested name field
print(test.name.name)
It's not the prettiest solution, but it is easy to implement and access.
Here's my solution for a descriptive error message.
def dict_key_needed(dictionary,key,msg='dictionary'):
try:
value = dictionary[key]
return value
except KeyError:
raise KeyError(f"{msg} is missing key '{key}'")
If you want to read name and value
dictionary={"name1":"value1","name2":"value2","name3":"value3","name4":"value4"}
for name,value in dictionary.items():
print(name)
print(value)
If you want to read name only
dictionary={"name1":"value1","name2":"value2","name3":"value3","name4":"value4"}
for name in dictionary:
print(name)
If you want to read value only
dictionary={"name1":"value1","name2":"value2","name3":"value3","name4":"value4"}
for values in dictionary.values():
print(values)
Here is your answer
dic1 = {"dic":1}
dic2 = {"dic":2}
dic3 = {"dic":3}
dictionaries = [dic1,dic2,dic3]
for i in range(len(dictionaries)):
my_var_name = [ k for k,v in locals().items() if v == dictionaries[i]][0]
print(my_var_name)
You should also consider adding a "name" key to each dictionary.
The names would be:
for dc in dict_list:
# Insert command that should replace ???
print 'The name of the dictionary is: ', dc['name']
Objects don't have names in Python and multiple names could be assigned to the same object.
However, an object-oriented way to do what you want would be to subclass the built-indict
dictionary class and add aname
property to it. Instances of it would behave exactly like normal dictionaries and could be used virtually anywhere a normal one could be.
class NamedDict(dict):
def __init__(self, *args, **kwargs):
try:
self._name = kwargs.pop('name')
except KeyError:
raise KeyError('a "name" keyword argument must be supplied')
super(NamedDict, self).__init__(*args, **kwargs)
@classmethod
def fromkeys(cls, name, seq, value=None):
return cls(dict.fromkeys(seq, value), name=name)
@property
def name(self):
return self._name
dict_list = [NamedDict.fromkeys('dict1', range(1,4)),
NamedDict.fromkeys('dicta', range(1,4), 'a'),
NamedDict.fromkeys('dict666', range(1,4), 666)]
for dc in dict_list:
print 'the name of the dictionary is ', dc.name
print 'the dictionary looks like ', dc
Output:
the name of the dictionary is dict1
the dictionary looks like {1: None, 2: None, 3: None}
the name of the dictionary is dicta
the dictionary looks like {1: 'a', 2: 'a', 3: 'a'}
the name of the dictionary is dict666
the dictionary looks like {1: 666, 2: 666, 3: 666}
Don't use a dict_list
, use a dict_dict
if you need their names. In reality, though, you should really NOT be doing this. Don't embed meaningful information in variable names. It's tough to get.
dict_dict = {'dict1':dict1, 'dicta':dicta, 'dict666':dict666}
for name,dict_ in dict_dict.items():
print 'the name of the dictionary is ', name
print 'the dictionary looks like ', dict_
Alternatively make a dict_set
and iterate over locals()
but this is uglier than sin.
dict_set = {dict1,dicta,dict666}
for name,value in locals().items():
if value in dict_set:
print 'the name of the dictionary is ', name
print 'the dictionary looks like ', value
Again: uglier than sin, but it DOES work.