我做了一个函数,它将在字典中查找年龄并显示匹配的名字:

dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
for age in dictionary.values():
    if age == search_age:
        name = dictionary[age]
        print name

我知道如何比较和查找年龄,只是不知道如何显示这个人的名字。此外,由于第5行,我得到了一个KeyError。我知道这是不正确的,但我不知道如何让它向后搜索。


当前回答

你可以通过使用dict.keys(), dict.values()和list.index()方法来获取key,参见下面的代码示例:

names_dict = {'george':16,'amber':19}
search_age = int(raw_input("Provide age"))
key = names_dict.keys()[names_dict.values().index(search_age)]

其他回答

没有。Dict不是这样使用的。

dictionary = {'george': 16, 'amber': 19}
search_age = input("Provide age")
for name, age in dictionary.items():  # for name, age in dictionary.iteritems():  (for Python 2.x)
    if age == search_age:
        print(name)

已经回答了,但由于一些人提到反转字典,下面是如何在一行中做到这一点(假设1:1映射)和一些各种性能数据:

python 2.6:

reversedict = dict([(value, key) for key, value in mydict.iteritems()])

+ 2.7:

reversedict = {value:key for key, value in mydict.iteritems()}

如果你认为不是1:1,你仍然可以用几行创建一个合理的反向映射:

reversedict = defaultdict(list)
[reversedict[value].append(key) for key, value in mydict.iteritems()]

这有多慢:比简单的搜索慢,但远没有你想象的那么慢——在一个“直接”100000条目的字典上,“快速”搜索(即查找键前面的值)比反转整个字典快10倍左右,而“缓慢”搜索(接近结尾)大约快4-5倍。所以最多查找10次,就能收回成本。

第二个版本(每个项目都有列表)大约是简单版本的2.5倍。

largedict = dict((x,x) for x in range(100000))

# Should be slow, has to search 90000 entries before it finds it
In [26]: %timeit largedict.keys()[largedict.values().index(90000)]
100 loops, best of 3: 4.81 ms per loop

# Should be fast, has to only search 9 entries to find it. 
In [27]: %timeit largedict.keys()[largedict.values().index(9)]
100 loops, best of 3: 2.94 ms per loop

# How about using iterkeys() instead of keys()?
# These are faster, because you don't have to create the entire keys array.
# You DO have to create the entire values array - more on that later.

In [31]: %timeit islice(largedict.iterkeys(), largedict.values().index(90000))
100 loops, best of 3: 3.38 ms per loop

In [32]: %timeit islice(largedict.iterkeys(), largedict.values().index(9))
1000 loops, best of 3: 1.48 ms per loop

In [24]: %timeit reversedict = dict([(value, key) for key, value in largedict.iteritems()])
10 loops, best of 3: 22.9 ms per loop

In [23]: %%timeit
....: reversedict = defaultdict(list)
....: [reversedict[value].append(key) for key, value in largedict.iteritems()]
....:
10 loops, best of 3: 53.6 ms per loop

过滤器也有一些有趣的结果。理论上,filter应该更快,因为我们可以使用itervalues(),而且可能不需要创建/遍历整个值列表。在实践中,结果是……奇怪的……

In [72]: %%timeit
....: myf = ifilter(lambda x: x[1] == 90000, largedict.iteritems())
....: myf.next()[0]
....:
100 loops, best of 3: 15.1 ms per loop

In [73]: %%timeit
....: myf = ifilter(lambda x: x[1] == 9, largedict.iteritems())
....: myf.next()[0]
....:
100000 loops, best of 3: 2.36 us per loop

因此,对于小偏移量,它比以前的任何版本都要快得多(2.36 *u*S vs.以前的情况下至少1.48 *m*S)。然而,对于接近列表末尾的大偏移量,它会显着变慢(15.1ms vs.相同的1.48mS)。以我之见,在低端产品上节省下来的少量成本,在高端产品上的成本是不值的。

my_dict = {'A': 19, 'B': 28, 'carson': 28}
search_age = 28

只拿一个

name = next((name for name, age in my_dict.items() if age == search_age), None)
print(name)  # 'B'

获取多个数据

name_list = [name for name, age in filter(lambda item: item[1] == search_age, my_dict.items())]
print(name_list)  # ['B', 'carson']
key = next((k for k in my_dict if my_dict[k] == val), None)

我瞥见所有的答案,没有提到简单地使用列表理解?

这个Python的单行解决方案可以返回任意数量的给定值的所有键(在Python 3.9.1中测试):

>>> dictionary = {'george' : 16, 'amber' : 19, 'frank': 19}
>>>
>>> age = 19
>>> name = [k for k in dictionary.keys() if dictionary[k] == age]; name
['george', 'frank']
>>>
>>> age = (16, 19)
>>> name = [k for k in dictionary.keys() if dictionary[k] in age]; name
['george', 'amber', 'frank']
>>>
>>> age = (22, 25)
>>> name = [k for k in dictionary.keys() if dictionary[k] in age]; name
[]