解析深度嵌套的Python字典/Tup

2024-06-26 00:10:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试解析/循环一个深度嵌套的字典/元组,例如:

#!/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或文本中读取它。。。你知道吗


Tags: inforage字典moredisplayactorsmovies
3条回答
# 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']

只需在访问值/值之前添加类型检查:

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

并非所有的值都是字典;有些是字符串:

# ...
'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

相关问题 更多 >