python:查找具有值的所有键
我有一本字典如下:python:查找具有值的所有键,python,python-3.x,nested,Python,Python 3.x,Nested,我有一本字典如下: mydict = {'a' : 'apple', 'b' : 'bobb', 'c' : { 'd' : 'dog' }, 'e' : 'dog' } In [23]: list(find_key(mydict)) Out[23]: ['e', 'c.d'] In [26]: mydict = {'a' : 'apple', 'b' : 'bobb', 'c' : {
mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog'
}
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
假设我想找到所有值为“dog
”的键,在嵌套的情况下,这些键应该用点分隔
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
因此,输出应该是一个列表['e','c.d']
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
现在,如果我用python 3编写下面的代码,它只输出“e
”
print(list(mydict.keys())[list(mydict.values()).index('dog')])
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
如何获取嵌套键?您可以使用如下递归函数:
def find_key(mydict, pre=tuple()):
for key, value in mydict.items():
if isinstance(value, dict):
yield from find_key(value, pre=pre+(key,))
elif value == 'dog':
if pre:
yield '.'.join(pre + (key,))
else:
yield key
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
测试:
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
您可以使用递归(尽管@Kasramvd比我更擅长,但这里有一个非生成器版本):
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
使用Kasramvd的messier测试用例:
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
>>> mydict = {'a' : 'apple',
... 'b' : 'bobb',
... 'c' : {
... 'd' : 'dog'
... },
... 'e' : 'dog',
... 'k':{'f':{'c':{'x':'dog'}}}}
>>> find_key('dog', mydict)
['c.d', 'e', 'k.f.c.x']
您还可以将递归与列表理解结合使用:
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
mydict1 = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog'
}
mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
s = [mydict1, mydict]
def get_val(d, target='dog'):
return reduce(lambda x, y:([x] if isinstance(x, str) else x)+([y] if isinstance(y, str) else y), list(filter(None, [a if b == target else "{}.{}".format(a, get_val(b)) if isinstance(b, dict) else None for a, b in d.items()])))
new_s = list(map(get_val, s))
输出:
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
[['c.d', 'e'], ['c.d', 'e', 'k.f.c.x']]
给你:
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}},
'p':{'r':{'h':{'m':{'n':{'o':{'a':{'b':{'t':{'z':{'a':{'b':{'c':{'d':{'e':{'f':{'g':'dog'}}}}}}}}}}}}}}}}
}
your_word='dog'
result = []
for key,value in mydict.items():
if value==your_word:
result.append(key)
elif isinstance(value,dict):
def recursive_approach(my_dict, nested_dict=key):
for i, j in my_dict.items():
if isinstance(j, dict):
nested_dict = "{}.{}".format(nested_dict, i)
return recursive_approach(j, nested_dict)
else:
if nested_dict == '':
if j == your_word:
result.append(i)
else:
if j == your_word:
result.append("{}.{}".format(nested_dict, i))
recursive_approach(value)
print(result)
输出:
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
['p.r.h.m.n.o.a.b.t.z.a.b.c.d.e.f.g', 'k.f.c.x', 'e', 'c.d']
做一个递归的
函数x
,搜索每个val中的狗
,并将每个dict
val发送到函数x
非生成器版本以获得良好的测量结果?虽然效率不高,也不太像蟒蛇!为了提高内存效率,我希望看到一个非递归解决方案,而不是一个使它更糟糕的非生成器解决方案@Kasramvd嗯,在我看到你已经提供了一个解决方案之前,我已经发布了它,也许我太喜欢它了。老实说,我不确定迭代解决方案是否有必要,如果嵌套深度超过10层,那么还存在其他问题