在字典中通过值返回键

5

我想要根据一个值在字典中返回对应的键。

在这个例子中,如果字典中有'b',我希望它返回'b'所对应的键(即2)。

def find_key(input_dict, value):
    if value in input_dict.values():
        return UNKNOWN            #This is a placeholder
    else:
        return "None"

print(find_key({1:'a', 2:'b', 3:'c', 4:'d'}, 'b'))

我想要得到的答案是关键词2,但我不确定应该输入什么来获得答案,请帮忙,非常感激。


你确定你的键值对映射方式是正确的吗? - jamylak
1
你可能被卡住了,因为你的数据结构不适合满足你的需求。 - Steven Rumbalski
2个回答

17

返回第一个匹配的键:

def find_key(input_dict, value):
    return next((k for k, v in input_dict.items() if v == value), None)

返回所有匹配的键作为一个集合:

def find_key(input_dict, value):
    return {k for k, v in input_dict.items() if v == value}

字典中的值不一定是唯一的。第一个选项如果没有匹配,则返回None,第二个选项在这种情况下返回空集。

由于字典的顺序是任意的(取决于使用了哪些键和插入和删除历史记录),因此被认为是“第一个”键也是任意的。

示例:

>>> def find_key(input_dict, value):
...     return next((k for k, v in input_dict.items() if v == value), None)
... 
>>> find_key({1:'a', 2:'b', 3:'c', 4:'d'}, 'b')
2
>>> find_key({1:'a', 2:'b', 3:'c', 4:'d'}, 'z') is None
True
>>> def find_key(input_dict, value):
...     return {k for k, v in input_dict.items() if v == value}
... 
>>> find_key({1:'a', 2:'b', 3:'c', 4:'d'}, 'b')
set([2])
>>> find_key({1:'a', 2:'b', 3:'c', 4:'d', 5:'b'}, 'b')
set([2, 5])
>>> find_key({1:'a', 2:'b', 3:'c', 4:'d'}, 'z')
set([])

请注意,每次需要搜索匹配键时,我们都需要循环遍历这些值。这不是最有效的方法,特别是如果您经常需要将值与键进行匹配。在这种情况下,请创建一个反向索引:

from collections import defaultdict

values_to_keys = defaultdict(set)

for key, value in input_dict:
    values_to_keys[value].add(key)

现在您可以直接在O(1)(常数)时间内请求密钥集:

keys = values_to_keys.get(value)

这里使用了集合;由于字典没有顺序,所以在这里使用集合更为合理。


1
+1 - 使用defaultdict(set)的好处很明显 ;) - Jon Clements

7
请将您的函数修改如下:
def find_key_for(input_dict, value):    
    for k, v in input_dict.items():
        if v == value:
            yield k

然后获取第一个键(如果不存在则为 None

print next(find_key_for(your_dict, 'b'), None)

获取所有职位:
keys = list(find_key_for(your_dict, 'b'))

或者,要获取'n'个键:

from itertools import islice
keys = list(islice(find_key_for(your_dict, 'b'), 5))

注意-你得到的键将以字典迭代的顺序为“n”个。
如果您经常这样做(并且您的值是可散列的),那么您可能希望转置字典。
from collections import defaultdict

dd = defaultdict(list)
for k, v in d.items():
    dd[v].append(k)

print dd['b']

很好。此外,如果值始终是唯一的,则可以在不使用defaultdict的情况下完成此操作。rev_d = {v:k for k,v in d.iteritems()} - Steven Rumbalski
在关于转置字典的部分,你可能还想加上“值是唯一的”这个条件。否则你就没有真正完成转置。但总体来说,很好的答案。+1 - mgilson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接