在python中迭代dict dict的dict

时间:2014-05-12 09:02:18

标签: python

我对dict的词典有所了解。我想要一个函数,如果争论与像<,p>这样的关键匹配,它将返回所有细节

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]

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

4 个答案:

答案 0 :(得分: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]

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

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'])

您可以进一步缩短代码,例如

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

如果在字典中找不到密钥并且在Python中被视为Falsy,则dict.get将返回None。因此,如果它不在主词典中,我们将检查子词典。

如果您使用的是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'])

答案 1 :(得分:2)

for key,value in identifiers.items():
        if key == p:
            return identifiers[key]        
        else:
            if p in identifiers[key]['subid']:
                return identifiers[key]['subid'][p]

答案 2 :(得分:2)

如果您确定psubid内,如果不在顶级,则可能会有以下内容。

def getdetails(p):
    req_val = identifiers.get(p)
    if not req_val:
       for key, value in identifiers.items():
            req_val = value['subid'].get(p)
    return req_val

答案 3 :(得分:2)

尝试这样的递归:

def getdetails(p, dictionary):
    result = []
    if type(dictionary) is not dict:
        return result
    for key in dictionary:
        if key == p:
            result.append(dictionary[p])
        result += getdetails(p, dictionary[key])

    return result

print getdetails('name', identifiers)
print getdetails('subid', identifiers)