通过字典中的值获取关键字
我做了一个函数,在字典中查找年龄并显示匹配的名字:
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”。