问题:通过字典中的值获取键

我制作了一个函数,该函数将查询年龄Dictionary并显示匹配的名称:

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

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

I made a function which will look up ages in a Dictionary and show the matching name:

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

I know how to compare and find the age I just don’t know how to show the name of the person. Additionally, I am getting a KeyError because of line 5. I know it’s not correct but I can’t figure out how to make it search backwards.


回答 0

空无一人。 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)

There is none. dict is not intended to be used this way.

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

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()如何从dict中获取值列表?.values()

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

Or in Python 3.x:

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

Basically, it separates the dictionary’s values in a list, finds the position of the value you have, and gets the key at that position.

More about keys() and .values() in Python 3: How can I get list of values from dict?


回答 2

如果你想同时姓名年龄,你应该用.items()它给你的关键(key, value)元组:

for name, age in mydict.items():
    if age == search_age:
        print name

您可以在for循环中将元组解压缩为两个单独的变量,然后匹配年龄。

如果您通常要按年龄查找,并且没有两个人具有相同的年龄,则还应该考虑反转字典。

{16: 'george', 19: 'amber'}

这样您就可以通过做

mydict[search_age]

我一直称其为,mydict而不是list因为它list是内置类型的名称,因此您不应将此名称用作其他名称。

您甚至可以在一行中获得所有给定年龄的人的列表:

[name for name, age in mydict.items() if age == search_age]

或每个年龄段只有一个人:

next((name for name, age in mydict.items() if age == search_age), None)

这只会给你 None如果没有那个年龄的人,。

最后,如果dict较长,并且您使用的是Python 2,则应考虑使用.iteritems()而不是.items()Cat Plus Plus在其答案中所做的操作,因为它不需要复制列表。

If you want both the name and the age, you should be using .items() which gives you key (key, value) tuples:

for name, age in mydict.items():
    if age == search_age:
        print name

You can unpack the tuple into two separate variables right in the for loop, then match the age.

You should also consider reversing the dictionary if you’re generally going to be looking up by age, and no two people have the same age:

{16: 'george', 19: 'amber'}

so you can look up the name for an age by just doing

mydict[search_age]

I’ve been calling it mydict instead of list because list is the name of a built-in type, and you shouldn’t use that name for anything else.

You can even get a list of all people with a given age in one line:

[name for name, age in mydict.items() if age == search_age]

or if there is only one person with each age:

next((name for name, age in mydict.items() if age == search_age), None)

which will just give you None if there isn’t anyone with that age.

Finally, if the dict is long and you’re on Python 2, you should consider using .iteritems() instead of .items() as Cat Plus Plus did in his answer, since it doesn’t need to make a copy of the list.


回答 3

我认为指出哪种方法最快,在哪种情况下会很有趣:

这是我运行的一些测试(在2012年的MacBook Pro上)

>>> def method1(list,search_age):
...     for name,age in list.iteritems():
...             if age == search_age:
...                     return name
... 
>>> def method2(list,search_age):
...     return [name for name,age in list.iteritems() if age == search_age]
... 
>>> def method3(list,search_age):
...     return list.keys()[list.values().index(search_age)]

profile.run()每种方法的结果100000次:

方法1:

>>> profile.run("for i in range(0,100000): method1(list,16)")
     200004 function calls in 1.173 seconds

方法2:

>>> profile.run("for i in range(0,100000): method2(list,16)")
     200004 function calls in 1.222 seconds

方法3:

>>> profile.run("for i in range(0,100000): method3(list,16)")
     400004 function calls in 2.125 seconds

因此,这表明对于小的字典而言,方法1最快。这很可能是因为它返回第一个匹配项,而不是像方法2那样的所有匹配项(请参见下面的注释)。


有趣的是,对我拥有2700个条目的字典执行相同的测试,我得到的结果却截然不同(这次运行10000次):

方法1:

>>> profile.run("for i in range(0,10000): method1(UIC_CRS,'7088380')")
     20004 function calls in 2.928 seconds

方法2:

>>> profile.run("for i in range(0,10000): method2(UIC_CRS,'7088380')")
     20004 function calls in 3.872 seconds

方法3:

>>> profile.run("for i in range(0,10000): method3(UIC_CRS,'7088380')")
     40004 function calls in 1.176 seconds

所以在这里,方法3是快。只是显示您的字典大小会影响您选择的方法。

注意:方法2返回所有名称的列表,而方法1和3仅返回第一个匹配项。我没有考虑内存使用情况。我不确定方法3是否创建2个额外的列表(keys()和values())并将其存储在内存中。

I thought it would be interesting to point out which methods are the quickest, and in what scenario:

Here’s some tests I ran (on a 2012 MacBook Pro)

>>> def method1(list,search_age):
...     for name,age in list.iteritems():
...             if age == search_age:
...                     return name
... 
>>> def method2(list,search_age):
...     return [name for name,age in list.iteritems() if age == search_age]
... 
>>> def method3(list,search_age):
...     return list.keys()[list.values().index(search_age)]

Results from profile.run() on each method 100000 times:

Method 1:

>>> profile.run("for i in range(0,100000): method1(list,16)")
     200004 function calls in 1.173 seconds

Method 2:

>>> profile.run("for i in range(0,100000): method2(list,16)")
     200004 function calls in 1.222 seconds

Method 3:

>>> profile.run("for i in range(0,100000): method3(list,16)")
     400004 function calls in 2.125 seconds

So this shows that for a small dict, method 1 is the quickest. This is most likely because it returns the first match, as opposed to all of the matches like method 2 (see note below).


Interestingly, performing the same tests on a dict I have with 2700 entries, I get quite different results (this time run 10000 times):

Method 1:

>>> profile.run("for i in range(0,10000): method1(UIC_CRS,'7088380')")
     20004 function calls in 2.928 seconds

Method 2:

>>> profile.run("for i in range(0,10000): method2(UIC_CRS,'7088380')")
     20004 function calls in 3.872 seconds

Method 3:

>>> profile.run("for i in range(0,10000): method3(UIC_CRS,'7088380')")
     40004 function calls in 1.176 seconds

So here, method 3 is much faster. Just goes to show the size of your dict will affect which method you choose.

Notes: Method 2 returns a list of all names, whereas methods 1 and 3 return only the first match. I have not considered memory usage. I’m not sure if method 3 creates 2 extra lists (keys() and values()) and stores them in memory.


回答 4

一线版本:(i是旧字典,p是反向字典)

说明:i.keys()i.values()返回两个分别具有字典键和值的列表。zip函数具有将列表捆绑在一起以生成字典的能力。

p = dict(zip(i.values(),i.keys()))

警告:仅当值是可哈希值且唯一时,此选项才起作用。

one line version: (i is an old dictionary, p is a reversed dictionary)

explanation : i.keys() and i.values() returns two lists with keys and values of the dictionary respectively. The zip function has the ability to tie together lists to produce a dictionary.

p = dict(zip(i.values(),i.keys()))

Warning : This will work only if the values are hashable and unique.


回答 5

a = {'a':1,'b':2,'c':3}
{v:k for k, v in a.items()}[1]

或更好

{k:v for k, v in a.items() if v == 1}
a = {'a':1,'b':2,'c':3}
{v:k for k, v in a.items()}[1]

or better

{k:v for k, v in a.items() if v == 1}

回答 6

key = next((k for k in my_dict if my_dict[k] == val), None)
key = next((k for k in my_dict if my_dict[k] == val), None)

回答 7

尝试以下这种单线来反向字典:

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

Try this one-liner to reverse a dictionary:

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

回答 8

我找到了这个答案非常有效,但对我来说却不太容易理解。

为了更加清晰,您可以反转字典的键和值。这是使键的值和值的键,因为看到这里

mydict = {'george':16,'amber':19}
res = dict((v,k) for k,v in mydict.iteritems())
print(res[16]) # Prints george

要么

mydict = {'george':16,'amber':19}
dict((v,k) for k,v in mydict.iteritems())[16]

这与其他答案基本相同。

I found this answer very effective but not very easy to read for me.

To make it more clear you can invert the key and the value of a dictionary. This is make the keys values and the values keys, as seen here.

mydict = {'george':16,'amber':19}
res = dict((v,k) for k,v in mydict.iteritems())
print(res[16]) # Prints george

or

mydict = {'george':16,'amber':19}
dict((v,k) for k,v in mydict.iteritems())[16]

which is essentially the same that this other answer.


回答 9

如果要通过值查找键,则可以使用字典理解来创建查找字典,然后使用该字典从值中查找键。

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

If you want to find the key by the value, you can use a dictionary comprehension to create a lookup dictionary and then use that to find the key from the value.

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

回答 10

您可以通过使用获取密钥dict.keys()dict.values()list.index()方法,请参见下面的代码示例:

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

You can get key by using dict.keys(), dict.values() and list.index() methods, see code samples below:

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

回答 11

这是我对这个问题的看法。:)我刚刚开始学习Python,所以我这样称呼:

“初学者的理解”解决方案。

#Code without comments.

list1 = {'george':16,'amber':19, 'Garry':19}
search_age = raw_input("Provide age: ")
print
search_age = int(search_age)

listByAge = {}

for name, age in list1.items():
    if age == search_age:
        age = str(age)
        results = name + " " +age
        print results

        age2 = int(age)
        listByAge[name] = listByAge.get(name,0)+age2

print
print listByAge

#Code with comments.
#I've added another name with the same age to the list.
list1 = {'george':16,'amber':19, 'Garry':19}
#Original code.
search_age = raw_input("Provide age: ")
print
#Because raw_input gives a string, we need to convert it to int,
#so we can search the dictionary list with it.
search_age = int(search_age)

#Here we define another empty dictionary, to store the results in a more 
#permanent way.
listByAge = {}

#We use double variable iteration, so we get both the name and age 
#on each run of the loop.
for name, age in list1.items():
    #Here we check if the User Defined age = the age parameter 
    #for this run of the loop.
    if age == search_age:
        #Here we convert Age back to string, because we will concatenate it 
        #with the person's name. 
        age = str(age)
        #Here we concatenate.
        results = name + " " +age
        #If you want just the names and ages displayed you can delete
        #the code after "print results". If you want them stored, don't...
        print results

        #Here we create a second variable that uses the value of
        #the age for the current person in the list.
        #For example if "Anna" is "10", age2 = 10,
        #integer value which we can use in addition.
        age2 = int(age)
        #Here we use the method that checks or creates values in dictionaries.
        #We create a new entry for each name that matches the User Defined Age
        #with default value of 0, and then we add the value from age2.
        listByAge[name] = listByAge.get(name,0)+age2

#Here we print the new dictionary with the users with User Defined Age.
print
print listByAge

#Results
Running: *\test.py (Thu Jun 06 05:10:02 2013)

Provide age: 19

amber 19
Garry 19

{'amber': 19, 'Garry': 19}

Execution Successful!

Here is my take on this problem. :) I have just started learning Python, so I call this:

“The Understandable for beginners” solution.

#Code without comments.

list1 = {'george':16,'amber':19, 'Garry':19}
search_age = raw_input("Provide age: ")
print
search_age = int(search_age)

listByAge = {}

for name, age in list1.items():
    if age == search_age:
        age = str(age)
        results = name + " " +age
        print results

        age2 = int(age)
        listByAge[name] = listByAge.get(name,0)+age2

print
print listByAge

.

#Code with comments.
#I've added another name with the same age to the list.
list1 = {'george':16,'amber':19, 'Garry':19}
#Original code.
search_age = raw_input("Provide age: ")
print
#Because raw_input gives a string, we need to convert it to int,
#so we can search the dictionary list with it.
search_age = int(search_age)

#Here we define another empty dictionary, to store the results in a more 
#permanent way.
listByAge = {}

#We use double variable iteration, so we get both the name and age 
#on each run of the loop.
for name, age in list1.items():
    #Here we check if the User Defined age = the age parameter 
    #for this run of the loop.
    if age == search_age:
        #Here we convert Age back to string, because we will concatenate it 
        #with the person's name. 
        age = str(age)
        #Here we concatenate.
        results = name + " " +age
        #If you want just the names and ages displayed you can delete
        #the code after "print results". If you want them stored, don't...
        print results

        #Here we create a second variable that uses the value of
        #the age for the current person in the list.
        #For example if "Anna" is "10", age2 = 10,
        #integer value which we can use in addition.
        age2 = int(age)
        #Here we use the method that checks or creates values in dictionaries.
        #We create a new entry for each name that matches the User Defined Age
        #with default value of 0, and then we add the value from age2.
        listByAge[name] = listByAge.get(name,0)+age2

#Here we print the new dictionary with the users with User Defined Age.
print
print listByAge

.

#Results
Running: *\test.py (Thu Jun 06 05:10:02 2013)

Provide age: 19

amber 19
Garry 19

{'amber': 19, 'Garry': 19}

Execution Successful!

回答 12

get_key = lambda v, d: next(k for k in d if d[k] is v)
get_key = lambda v, d: next(k for k in d if d[k] is v)

回答 13

考虑使用熊猫。正如William McKinney的“ Python for Data Analysis”中所述

考虑序列的另一种方法是定长排序的字典,因为它是索引值到数据值的映射。它可以在可能使用字典的许多情况下使用。

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)

Consider using Pandas. As stated in William McKinney’s “Python for Data Analysis’

Another way to think about a Series is as a fixed-length, ordered dict, as it is a mapping of index values to data values. It can be used in many contexts where you might use a dict.

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

To query your series do the following:

lookup_list[lookup_list.values == 19]

Which yields:

Out[1]: 
amber    19
dtype: int64

If you need to do anything else with the output transforming the answer into a list might be useful:

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

回答 14

在这里,recover_key将使用字典和要在字典中找到的值。然后,我们遍历字典中的键,并与value的键进行比较,然后返回该特定键。

def recover_key(dicty,value):
    for a_key in dicty.keys():
        if (dicty[a_key] == value):
            return a_key

Here, recover_key takes dictionary and value to find in dictionary. We then loop over the keys in dictionary and make a comparison with that of value and return that particular key.

def recover_key(dicty,value):
    for a_key in dicty.keys():
        if (dicty[a_key] == value):
            return a_key

回答 15

for name in mydict:
    if mydict[name] == search_age:
        print(name) 
        #or do something else with it. 
        #if in a function append to a temporary list, 
        #then after the loop return the list
for name in mydict:
    if mydict[name] == search_age:
        print(name) 
        #or do something else with it. 
        #if in a function append to a temporary list, 
        #then after the loop return the list

回答 16

我们可以得到Keydict是:

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

we can get the Key of dict by :

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

回答 17

它得到了回答,但是可以通过使用“ map / reduce”来完成,例如:

def find_key(value, dictionary):
    return reduce(lambda x, y: x if x is not None else y,
                  map(lambda x: x[0] if x[1] == value else None, 
                      dictionary.iteritems()))

it’s answered, but it could be done with a fancy ‘map/reduce’ use, e.g.:

def find_key(value, dictionary):
    return reduce(lambda x, y: x if x is not None else y,
                  map(lambda x: x[0] if x[1] == value else None, 
                      dictionary.iteritems()))

回答 18

Cat Plus Plus提到,这不是打算使用字典的方式。原因如下:

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

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

当您通过键的对应值查找键时,实际上就是在反转字典。但是,映射不一定是可逆的!在此示例中,请求对应于v1的密钥可能会产生k1或k3。您应该同时退货吗?只是找到第一个?这就是为什么字典未定义indexof()的原因。

如果您知道自己的数据,则可以这样做。但是API不能假定任意字典都是可逆的,因此缺少这种操作。

Cat Plus Plus mentioned that this isn’t how a dictionary is intended to be used. Here’s why:

The definition of a dictionary is analogous to that of a mapping in mathematics. In this case, a dict is a mapping of K (the set of keys) to V (the values) – but not vice versa. If you dereference a dict, you expect to get exactly one value returned. But, it is perfectly legal for different keys to map onto the same value, e.g.:

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

When you look up a key by it’s corresponding value, you’re essentially inverting the dictionary. But a mapping isn’t necessarily invertible! In this example, asking for the key corresponding to v1 could yield k1 or k3. Should you return both? Just the first one found? That’s why indexof() is undefined for dictionaries.

If you know your data, you could do this. But an API can’t assume that an arbitrary dictionary is invertible, hence the lack of such an operation.


回答 19

这是我的看法。万一您需要一个结果,这对于显示多个结果很有用。所以我也添加了列表

myList = {'george':16,'amber':19, 'rachel':19, 
           'david':15 }                         #Setting the dictionary
result=[]                                       #Making ready of the result list
search_age = int(input('Enter age '))

for keywords in myList.keys():
    if myList[keywords] ==search_age:
    result.append(keywords)                    #This part, we are making list of results

for res in result:                             #We are now printing the results
    print(res)

就是这样…

here is my take on it. This is good for displaying multiple results just in case you need one. So I added the list as well

myList = {'george':16,'amber':19, 'rachel':19, 
           'david':15 }                         #Setting the dictionary
result=[]                                       #Making ready of the result list
search_age = int(input('Enter age '))

for keywords in myList.keys():
    if myList[keywords] ==search_age:
    result.append(keywords)                    #This part, we are making list of results

for res in result:                             #We are now printing the results
    print(res)

And that’s it…


回答 20

d= {'george':16,'amber':19}

dict((v,k) for k,v in d.items()).get(16)

输出如下:

-> prints george
d= {'george':16,'amber':19}

dict((v,k) for k,v in d.items()).get(16)

The output is as follows:

-> prints george

回答 21

没有一种简单的方法可以通过“查找”值在列表中找到键。但是,如果您知道该值(通过键进行迭代),则可以通过该元素在字典中查找值。如果D [element](其中D是字典对象)等于您要查找的键,则可以执行一些代码。

D = {'Ali': 20, 'Marina': 12, 'George':16}
age = int(input('enter age:\t'))  
for element in D.keys():
    if D[element] == age:
        print(element)

There is no easy way to find a key in a list by ‘looking up’ the value. However, if you know the value, iterating through the keys, you can look up values in the dictionary by the element. If D[element] where D is a dictionary object, is equal to the key you’re trying to look up, you can execute some code.

D = {'Ali': 20, 'Marina': 12, 'George':16}
age = int(input('enter age:\t'))  
for element in D.keys():
    if D[element] == age:
        print(element)

回答 22

您需要使用字典,然后反向使用该字典。这意味着您需要另一个数据结构。如果您使用的是python 3,请使用enum模块,但如果使用的是python 2.7,请使用enum34python 2的反向移植。

例:

from enum import Enum

class Color(Enum): 
    red = 1 
    green = 2 
    blue = 3

>>> print(Color.red) 
Color.red

>>> print(repr(Color.red)) 
<color.red: 1=""> 

>>> type(Color.red) 
<enum 'color'=""> 
>>> isinstance(Color.green, Color) 
True 

>>> member = Color.red 
>>> member.name 
'red' 
>>> member.value 
1 

You need to use a dictionary and reverse of that dictionary. It means you need another data structure. If you are in python 3, use enum module but if you are using python 2.7 use enum34 which is back ported for python 2.

Example:

from enum import Enum

class Color(Enum): 
    red = 1 
    green = 2 
    blue = 3

>>> print(Color.red) 
Color.red

>>> print(repr(Color.red)) 
<color.red: 1=""> 

>>> type(Color.red) 
<enum 'color'=""> 
>>> isinstance(Color.green, Color) 
True 

>>> member = Color.red 
>>> member.name 
'red' 
>>> member.value 
1 

回答 23

def get_Value(dic,value):
    for name in dic:
        if dic[name] == value:
            del dic[name]
            return name
def get_Value(dic,value):
    for name in dic:
        if dic[name] == value:
            del dic[name]
            return name

回答 24

只是我的回答lambdafilter

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age  , dictionary )

Just my answer in lambda and filter.

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age  , dictionary )

回答 25

已经回答了,但是由于有几个人提到反转字典,因此这是您在一行中进行操作的方式(假设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

使用ifilter也有一些有趣的结果。从理论上讲,ifilter应该更快,因为我们可以使用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,而以前的版本最低为1.48 * m * S)。但是,对于列表末尾附近的较大偏移量,它的速度要慢得多(15.1ms与相同的1.48mS)。恕我直言,低端的少量节省不值得高端的成本。

already been answered, but since several people mentioned reversing the dictionary, here’s how you do it in one line (assuming 1:1 mapping) and some various perf data:

python 2.6:

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

2.7+:

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

if you think it’s not 1:1, you can still create a reasonable reverse mapping with a couple lines:

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

how slow is this: slower than a simple search, but not nearly as slow as you’d think – on a ‘straight’ 100000 entry dictionary, a ‘fast’ search (i.e. looking for a value that should be early in the keys) was about 10x faster than reversing the entire dictionary, and a ‘slow’ search (towards the end) about 4-5x faster. So after at most about 10 lookups, it’s paid for itself.

the second version (with lists per item) takes about 2.5x as long as the simple version.

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

Also had some interesting results with ifilter. Theoretically, ifilter should be faster, in that we can use itervalues() and possibly not have to create/go through the entire values list. In practice, the results were… odd…

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

So, for small offsets, it was dramatically faster than any previous version (2.36 *u*S vs. a minimum of 1.48 *m*S for previous cases). However, for large offsets near the end of the list, it was dramatically slower (15.1ms vs. the same 1.48mS). The small savings at the low end is not worth the cost at the high end, imho.


回答 26

有时可能需要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

Sometimes int() may be needed:

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

回答 27

这是一个在Python 2和Python 3中都可以使用的解决方案。

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

直到[search_age]构造反向字典为止(其中值是键,反之亦然)。您可以创建一个辅助方法,该方法将缓存此反向字典,如下所示:

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)

请注意,由于前者是预定义类型,因此我将其重命名listages_by_name

Here is a solution which works both in Python 2 and Python 3:

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

The part until [search_age] constructs the reverse dictionary (where values are keys and vice-versa). You could create a helper method which will cache this reversed dictionary like so:

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

or even more generally a factory which would create a by-age name lookup method for one or more of you lists

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]

so you would be able to do:

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

Note that I renamed list to ages_by_name since the former is a predefined type.


回答 28

这是您访问字典以执行所需操作的方式:

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

当然,您的名字太不正确了,看起来好像要打印一个年龄,但确实可以打印出名字。由于您是按名称访问的,因此如果您输入以下内容,它将变得更加容易理解:

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

更好的是:

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

This is how you access the dictionary to do what you want:

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

of course, your names are so off it looks like it would be printing an age, but it DOES print the name. Since you are accessing by name, it becomes more understandable if you write:

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

Better yet:

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

回答 29

dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
key = [filter( lambda x: dictionary[x] == k  , dictionary ),[None]][0] 
# key = None from [None] which is a safeguard for not found.

对于多次出现,请使用:

keys = [filter( lambda x: dictionary[x] == k  , dictionary )]
dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
key = [filter( lambda x: dictionary[x] == k  , dictionary ),[None]][0] 
# key = None from [None] which is a safeguard for not found.

For multiple occurrences use:

keys = [filter( lambda x: dictionary[x] == k  , dictionary )]

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。