我试图解析/循环一个深层嵌套的字典/元组,如下所示:
#!/usr/bin/env python
movies = {
'in_bruges': {
'display': 'In Bruges',
'actors': {
'Colin Farrel': {
'age': '99',
'height': '160'
},
'Brendan Gleeson': {
'age': '88',
'height': '158'
}
# many more...
}
},
'fargo': {
'display': 'Fargo',
'actors': {
'William H. Macy': {
'age': '109',
'height': '120'
},
'Steve Buscemi': {
'age': '11',
'height': '118'
}
# many more...
}
}
# many more...
}
我可以很好地访问各个字段:
print(movies['in_bruges']['actors']['Brendan Gleeson']['age']);
88
但是我很难完成整个事情。这就是我到目前为止......
for movie, val in movies.iteritems():
print movie
for v in val.values():
print v
for x in v.values(): # <-- BREAKS HERE
print x
错误:
AttributeError: 'str' object has no attribute 'values'
我明白为什么它会破裂......只是不确定如何解决它。此外,也许更重要的是,有更好的方法吗?这是字典和元组的混合(如果我错了,请纠正我)。我应该采用不同的结构吗?或者完全使用不同的方法?我宁愿不从csv或文本中读取它......
答案 0 :(得分:2)
只需在访问values / value之前添加类型检查:
isinstance(v, dict)
或
isinstance(v, basestring)
代码将是:
for movie, val in movies.iteritems():
print movie
for v in val.values():
if isinstance(v, dict):
for x in v.values():
print x
elif isinstance(v, basestring):
print v
答案 1 :(得分:1)
并非所有的价值观都是字典;一些是字符串:
# ...
'in_bruges': {
'display': 'In Bruges',
'actors': {
# ...
那是一个字符串和一本字典。您必须改变您的处理方式:
for movie, val in movies.iteritems():
print movie
for v in val.values():
if hasattr(v, 'values'):
for x in v.values():
print x
else:
print v
这里我使用了 ducktyping ;检查我想要使用的方法,而不是类型;如果它存在,我们假设它可以被视为字典。您也可以使用isinstance(v, dict)
,但上述内容更灵活,因为它允许使用正确方法处理任何内容。
您可以使用递归来处理任意深度的任意值:
def print_dictionary(d, indent=0):
try:
for k, v in d.iteritems():
print (indent * ' '), k, '->'
print_dictionary(v, indent + 1)
except AttributeError:
print (indent * ' '), d
这里我使用了异常处理;如果dict.iteritems()
方法不存在,则会引发AttributeError
。这种技术称为在你跳跃之前看。
使用您的演示词典输出:
>>> print_dictionary(movies)
fargo ->
actors ->
William H. Macy ->
age ->
109
height ->
120
Steve Buscemi ->
age ->
11
height ->
118
display ->
Fargo
in_bruges ->
actors ->
Brendan Gleeson ->
age ->
88
height ->
158
Colin Farrel ->
age ->
99
height ->
160
display ->
In Bruges
答案 2 :(得分:1)
# for all movies
for movie, movie_details in movies.iteritems():
print movie
display = movie_details['display']
print display
# for all actors in this movie
for actor,actor_details in movie_details['actors'].iteritems():
print actor
print actor_details['age']
print actor_details['height']