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

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。我知道这是不正确的,但我不知道如何让它向后搜索。


当前回答

mydict = {'george': 16, 'amber': 19}
print mydict.keys()[mydict.values().index(16)]  # Prints george

或者在Python 3.x中:

mydict = {'george': 16, 'amber': 19}
print(list(mydict.keys())[list(mydict.values()).index(16)])  # Prints george

基本上,它将字典的值分离到一个列表中,找到所拥有值的位置,并在该位置获取键。

更多关于Python 3中的keys()和.values():如何从dict获取值列表?

其他回答

考虑使用Pandas。正如William McKinney的《Python for Data Analysis》中所述

另一种考虑级数的方法是固定长度的有序级数 Dict,因为它是索引值到数据值的映射。它可以是 在很多情况下,你可能会用到字典。

import pandas as pd
list = {'george':16,'amber':19}
lookup_list = pd.Series(list)

要查询您的系列,请执行以下操作:

lookup_list[lookup_list.values == 19]

收益率:

Out[1]: 
amber    19
dtype: int64

如果您需要对输出进行任何其他转换 回答成一个列表可能有用:

answer = lookup_list[lookup_list.values == 19].index
answer = pd.Index.tolist(answer)

下面是一个在python2和python3中都适用的解决方案:

dict((v, k) for k, v in list.items())[search_age]

直到[search_age]的部分构造反向字典(其中值是键,反之亦然)。 你可以创建一个helper方法来缓存这个反向字典,就像这样:

def find_name(age, _rev_lookup=dict((v, k) for k, v in ages_by_name.items())):
    return _rev_lookup[age]

或者更一般的是一个工厂,它会为你的一个或多个列表创建一个按年龄查找的方法

def create_name_finder(ages_by_name):
    names_by_age = dict((v, k) for k, v in ages_by_name.items())
    def find_name(age):
      return names_by_age[age]

所以你可以这样做:

find_teen_by_age = create_name_finder({'george':16,'amber':19})
...
find_teen_by_age(search_age)

注意,我将list重命名为ages_by_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)。以我之见,在低端产品上节省下来的少量成本,在高端产品上的成本是不值的。

你可以通过使用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)]

试试下面的一行代码来反转字典:

reversed_dictionary = dict(map(reversed, dictionary.items()))