1

可能重复:
逆字典查找 - Python

是否有一种内置方法可以在 Python 中按值索引字典。

例如:

dict = {'fruit':'apple','colour':'blue','meat':'beef'}
print key where dict[key] == 'apple'

或者:

dict = {'fruit':['apple', 'banana'], 'colour':'blue'}
print key where 'apple' in dict[key]

还是我必须手动循环它?

4

3 回答 3

5

您可以使用列表理解

my_dict = {'fruit':'apple','colour':'blue','meat':'beef'}
print [key for key, value in my_dict.items() if value == 'apple']

上面的代码几乎完全符合您的要求:

打印键,其中 dict[key] == 'apple'

列表理解正在遍历字典items方法给出的所有键值对,并创建一个值为“apple”的所有键的新列表。

正如 Niklas 指出的那样,当您的值可能是列表时,这不起作用。在这种情况下,您必须小心使用in,因为'apple' in 'pineapple' == True. 因此,坚持使用列表理解方法需要进行一些类型检查。因此,您可以使用如下辅助函数:

def equals_or_in(target, value):
    """Returns True if the target string equals the value string or,
    is in the value (if the value is not a string).
    """
    if isinstance(target, str):
        return target == value
    else:
        return target in value

然后,下面的列表理解将起作用:

my_dict = {'fruit':['apple', 'banana'], 'colour':'blue'}
print [key for key, value in my_dict.items() if equals_or_in('apple', value)]
于 2012-04-04T16:44:05.750 回答
4

您必须手动循环它,但如果您需要反复查找,这是一个方便的技巧:

d1 = {'fruit':'apple','colour':'blue','meat':'beef'}

d1_rev = dict((v, k) for k, v in d1.items())

然后,您可以像这样使用反向字典:

>>> d1_rev['blue']
'colour'
>>> d1_rev['beef']
'meat'
于 2012-04-04T16:43:34.730 回答
3

您的要求比您意识到的要复杂:

  • 您需要同时处理列表值和普通值
  • 您实际上不需要取回密钥,而是取回密钥列表

你可以分两步解决这个问题:

  1. 规范化字典,使每个值都是一个列表(每个普通值都成为一个单元素)
  2. 建立一个反向字典

以下函数将解决此问题:

from collections import defaultdict

def normalize(d):
    return { k:(v if isinstance(v, list) else [v]) for k,v in d.items() }

def build_reverse_dict(d):
    res = defaultdict(list)
    for k,values in normalize(d).items():
        for x in values:
            res[x].append(k)
    return dict(res)

像这样使用:

>>> build_reverse_dict({'fruit':'apple','colour':'blue','meat':'beef'})
{'blue': ['colour'], 'apple': ['fruit'], 'beef': ['meat']}
>>> build_reverse_dict({'fruit':['apple', 'banana'], 'colour':'blue'})
{'blue': ['colour'], 'apple': ['fruit'], 'banana': ['fruit']}
>>> build_reverse_dict({'a':'duplicate', 'b':['duplicate']})
{'duplicate': ['a', 'b']}

因此,您只需构建一次反向字典,然后按值查找并返回键列表。

于 2012-04-04T16:50:25.340 回答