Ответ 1
def recurse(d):
if type(d)==type({}):
for k in d:
recurse(d[k])
else:
print d
Есть ли простой способ итерации по вложенному словарю, который может состоять из других объектов, таких как списки, кортежи, а затем словари, чтобы итерация охватывала все элементы этих других объектов?
Например, если я нахожу ключ вложенного словарного объекта, я бы получил все это в интерпретаторе Python.
[edit] Вот пример словаря:
{
'key_1': 'value_1',
'key_2': {'key_21': [(2100, 2101), (2110, 2111)],
'key_22': ['l1', 'l2'],
'key_23': {'key_231': 'v'},
'key_24': {'key_241': 502,
'key_242': [(5, 0), (7, 0)],
'key_243': {'key_2431': [0, 0],
'key_2432': 504,
'key_2433': [(11451, 0), (11452, 0)]
},
'key_244': {'key_2441': {'key_24411': {'key_244111': 'v_24411',
'key_244112': [(5549, 0)]
},
'key_24412':'v_24412'
},
'key_2441': ['ll1', 'll2']
}
},
}
}
жаль, что я не читаю, но я сделал все, что мог.
def recurse(d):
if type(d)==type({}):
for k in d:
recurse(d[k])
else:
print d
Генераторная версия Graddy recurse()
отвечает выше, которая не должна взорваться на строках, а также дает вам составной ключ (cookie crumb trail?), показывающий, как вы достигли определенного значения:
def recurse(d, keys=()):
if type(d) == dict:
for k in d:
for rv in recurse(d[k], keys + (k, )):
yield rv
else:
yield (keys, d)
for compound_key, val in recurse(eg_dict):
print '{}: {}'.format(compound_key, val)
выводит вывод (используя примерный словарь, содержащийся в вопросе):
('key_1',): value_1
('key_2', 'key_21'): [(2100, 2101), (2110, 2111)]
('key_2', 'key_22'): ['l1', 'l2']
('key_2', 'key_23', 'key_231'): v
('key_2', 'key_24', 'key_241'): 502
('key_2', 'key_24', 'key_243', 'key_2433'): [(11451, 0), (11452, 0)]
('key_2', 'key_24', 'key_243', 'key_2432'): 504
('key_2', 'key_24', 'key_243', 'key_2431'): [0, 0]
('key_2', 'key_24', 'key_242'): [(5, 0), (7, 0)]
('key_2', 'key_24', 'key_244', 'key_2441'): ['ll1', 'll2']
В Python 3 второй цикл возврата должен быть заменен на yield from
. Этот генератор можно сделать более общим, заменив тег type(d) == dict
на isinstance(d, collections.Mapping)
, используя Mapping ABC из модуля коллекций.
Вот еще одно решение,
#!/usr/bin/python
d = {'key_1': 'value_1',
'key_2': {'key_21': [(2100, 2101), (2110, 2111)],
'key_22': ['l1', 'l2'],
'key_23': {'key_231': 'v'},
'key_24': {'key_241': 502,
'key_242': [(5, 0), (7, 0)],
'key_243': {'key_2431': [0, 0],
'key_2432': 504,
'key_2433': [(11451, 0), (11452, 0)]},
'key_244': {'key_2441': ['ll1', 'll2']}}}}
def search_it(nested, target):
found = []
for key, value in nested.iteritems():
if key == target:
found.append(value)
elif isinstance(value, dict):
found.extend(search_it(value, target))
elif isinstance(value, list):
for item in value:
if isinstance(item, dict):
found.extend(search_it(item, target))
else:
if key == target:
found.append(value)
return found
keys = [ 'key_242', 'key_243', 'key_242', 'key_244', 'key_1' ]
for key in keys:
f = search_it(d, key)
print 'Key: %s, value: %s' % (key, f[0])
Вывод:
Key: key_242, value: [(5, 0), (7, 0)]
Key: key_243, value: {'key_2433': [(11451, 0), (11452, 0)], 'key_2432': 504, 'key_2431':
[0, 0]}
Key: key_242, value: [(5, 0), (7, 0)]
Key: key_244, value: {'key_2441': ['ll1', 'll2']}
Key: key_1, value: value_1
Итерация по вложенному словарю, содержащему неожиданные вложенные элементы.
Вот мое решение:
# d is the nested dictionary
for item in d:
if type(item) == list:
print "Item is a list"
for i in item: print i
elif type(item) == dict:
print "Item is a dict"
for i in item: print i
elif type(item) == tuple:
print "Item is a tuple"
for i in item: print i
else:
print "Item is not a list, neither a dict and not even a tuple"
print item
Я думаю, что приведенный выше пример очень общий, вы можете формовать его для своего случая использования.
Как использовать генератор обертки общего назначения, как показано ниже:
def recursive(coll):
"""Return a generator for all atomic values in coll and its subcollections.
An atomic value is one that not iterable as determined by iter."""
try:
k = iter(coll)
for x in k:
for y in recursive(x):
yield y
except TypeError:
yield coll
def test():
t = [[1,2,3], 4, 5, [6, [7, 8], 9]]
for x in recursive(t):
print x