在python中迭代dict dict的dict

Dip*_*ole 2 python

我对dict的词典有所了解.我想要一个函数,如果争论与键匹配,将返回所有细节,如,

identifiers = {
     '42566431313931326462642d3533656132352033': {         
         'name': 'topleft',         
         'subid': {
            'a3e54b84450000': {
                'name': 'north'                
            }
        }        
    },
    '0942378098093': {         
         'name': 'topright',         
         'subid': {
            '4b840000100000000000': {
                'name': 'north'                
            }
        }        
    },
    '4256643131ra98892389': {         
         'name': 'bottomleft',         
         'subid': {
            'a3e54b840000100000000000': {
                'name': 'west'                
            }
        }        
    }
}

def getdetails(p):
    # p could be key of dict or dict of dict
    for key in identifiers:
        if key == p:
            return identifiers[key]        
        else:
            if p in identifiers[key]['subid']:
                return identifiers[key]['subid'][p]
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更好的方法(可能是使用map和lambda)?

the*_*eye 5

可读性很重要.由于您的代码是可读的,我会略微改进代码,就像这样

def getdetails(p):
    if p in ids:
        return ids[p]

    for k, v in ids.iteritems():
        if p in v['subid']:
            return v['subid'][p]
Run Code Online (Sandbox Code Playgroud)

但是如果你正在寻找单行,你可以创建一个生成器表达式并返回从中得到的第一个值.

def getdetails(p):
    if p in ids: return ids[p]
    return next(v['subid'][p] for k, v in ids.iteritems() if p in v['subid'])
Run Code Online (Sandbox Code Playgroud)

您可以像这样进一步缩短代码

def getdetails(p):
    return ids.get(p) or next(v['subid'][p] for k, v in ids.iteritems() if p in v['subid'])
Run Code Online (Sandbox Code Playgroud)

dict.get将返回None如果该键没有在字典中找到,并且被认为是Falsy在Python.因此,如果它不在主词典中,我们将检查子词典.

如果您使用的是Python 3.x,则需要使用items方法而不是iteritems像这样

def getdetails(p):
    return ids.get(p) or next(v['subid'][p] for k, v in ids.items() if p in v['subid'])
Run Code Online (Sandbox Code Playgroud)