通过字典中的值获取关键字

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

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

我知道如何比较和发现年龄,我只是不知道如何显示这个人的名字。 此外,由于第5行,我得到一个KeyError 。我知道这是不正确的,但我不知道向后search。

没有。 dict不打算用这种方式。

 for name, age in list.iteritems(): if age == search_age: print name 
 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 

基本上,它将列表中的字典值分开,find你所拥有的值的位置,并获得该位置的密钥。

更多关于Python 3中的keys().values() : Python:从dict获取值列表最简单的方法?

如果你想要的名字年龄,你应该使用.items()给你的关键(key, value)元组:

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

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

你也应该考虑翻译字典,如果你一般会按年龄抬头,没有两个人有同样的年龄:

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

所以你可以通过做一个年龄的名字

 mydict[search_age] 

我一直把它mydict而不是list因为list是内置types的名字,你不应该把这个名字用于别的。

你甚至可以在一行中列出一个给定年龄的所有人:

 [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在他的答案中做的,因为它不需要复制名单。

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

以下是我运行的一些testing(在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(见下面的注释)的所有匹配。


有趣的是,在一个字典上执行相同的testing,我有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 快得多。 只是去显示你的字典的大小会影响你select的方法。

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

一行版本:(我是一个老字典,p是一个反向字典)

 p = dict(zip(i.values(),i.keys())) 
 lKey = [key for key, value in lDictionary.iteritems() if value == lValue][0] 
 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} 

这是我的这个问题。 :)我刚开始学习Python,所以我打电话给:

“对于初学者是可以理解的”解决scheme。

 #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! 

您可以通过使用dict.keys()list.index()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)] 
 for name in mydict.keys(): 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 

如果您想通过值来查找关键字,则可以使用字典理解来创build查找字典,然后使用它来从值中查找关键字。

 lookup = {value: key for key, value in self.data} lookup[value] 
 def get_Value(dic,value): for name in dic: if dic[name] == value: del dic[name] return name 

考虑使用pandas。 正如William McKinney的“用于数据分析的Python”

另一种思考系列的方法是固定长度,有序的字典,因为它是索引值到数据值的映射。 它可以用在你可能使用字典的许多上下文中。

 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) 

这是回答,但它可以做一个奇特的“地图/减less”使用,例如:

 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())) 

没有简单的方法通过查找价值来find列表中的关键字。 但是,如果您知道该值,则遍历这些键,可以通过该元素在字典中查找值。 如果其中D是字典对象的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) 

Cat Plus Plus提到,这不是一个字典是如何使用的。 原因如下:

字典的定义类似于math映射的定义。 在这种情况下,字典是K(键集)到V(值)的映射 – 但反之亦然。 如果您取消了一个字典,您希望只返回一个值。 但是,对于不同的键映射到相同的值是完全合法的,例如:

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

当你通过对应的值查找关键字时,你基本上是反转字典。 但映射不一定是可逆的! 在这个例子中,要求对应于v1的密钥可以产生k1或k3。 你应该回来吗? 只是第一个find? 这就是为什么indexof()对于字典没有定义的原因。

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

这是我的承担。 这是很好的显示多个结果,以防万一你需要一个。 所以我也添加了列表

 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) 

就是这样

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

你需要使用字典和反向的字典。 这意味着你需要另一个数据结构。 如果你是在python 3,使用enum模块,但如果您使用Python 2.7使用后端移植到Python 2的enum34

例:

 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 
 def recover_key(dictionary,value): for a_key in dicty.keys(): if (dicty[a_key] == value): return a_key 

已经被回答了,但是由于有几个人提到翻译字典,这里是你如何做一行(假设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,你仍然可以用几行代码创build一个合理的反向映射:

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

这个速度有多慢:比简单的search慢,但不像你想象的那么慢 – 在“直线”100000条目字典上,“快速”search(即寻找应该在键的早期的值)翻译整本字典的速度要快10倍左右,而“缓慢”的search速度大约快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(),可能不需要创build/遍历整个值列表。 在实践中,结果是…奇怪的…

 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)。 低端的小额储蓄是不值得的高端,恕我直言。

这就是你如何访问字典来做你想做的事情:

 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 

我希望这可以帮助…

 for key in list: if list[key] == search_value: return key 
 d= {'george':16,'amber':19} dict((v,k) for k,v in d.items()).get(16) 

输出如下:

 -> prints george 

这是一个可以在Python 2和Python 3中使用的解决scheme:

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

直到[search_age]构build反向字典的部分(其中值是键,反之亦然)。 你可以创build一个辅助方法来caching这个反转的字典,如下所示:

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

甚至更普遍的是一个为一个或多个列表创build按年龄查询名称的工厂

 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因为前者是预定义的types。

我知道这是旧的,但你可以很容易地find列表中的所有人与您的search年龄使用列表理解。

 ages = {'george':16,'amber':19} search = 16 print([name for (name, age) in ages.items() if age == search]) 

一个简单的方法可以做到这一点:

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

这将返回与search_age匹配的值的键列表。 如果需要,也可以用其他条件语句replace“list == search_age”。