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

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


当前回答

有时可能需要int():

titleDic = {'Фильмы':1, 'Музыка':2}

def categoryTitleForNumber(self, num):
    search_title = ''
    for title, titleNum in self.titleDic.items():
        if int(titleNum) == int(num):
            search_title = title
    return search_title

其他回答

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

已经回答了,但由于一些人提到反转字典,下面是如何在一行中做到这一点(假设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)。以我之见,在低端产品上节省下来的少量成本,在高端产品上的成本是不值的。

Cat Plus Plus提到,字典并不是这样使用的。原因如下:

字典的定义类似于数学中的映射。在这种情况下,字典是K(键集)到V(值)的映射-反之亦然。如果对字典进行解引用,则希望只返回一个值。但是,不同的键映射到相同的值是完全合法的,例如:

d = { k1 : v1, k2 : v2, k3 : v1}

当你根据键的对应值查找它时,你实际上是在颠倒字典。但是映射并不一定是可逆的!在这个例子中,请求v1对应的键可以得到k1或k3。你应该把两者都退回吗?只是第一个发现的?这就是为什么indexof()对于字典是未定义的。

如果你知道你的数据,你可以这样做。但是API不能假设任意字典是可逆的,因此缺少这样的操作。

我们可以通过以下方法得到dict的Key:

def getKey(dct,value):
     return [key for key in dct if (dct[key] == value)]

如果希望根据值查找键,可以使用字典推导式创建查找字典,然后使用该字典从值中查找键。

lookup = {value: key for key, value in self.data}
lookup[value]