根据字典中的值获取键
- 2024-11-25 08:49:00
- admin 原创
- 216
问题描述:
我创建了一个函数,它可以查找年龄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 行。我知道它不正确,但我不知道如何让它向后搜索。
解决方案 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()
解决方案 2:
没有。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)
解决方案 3:
如果您想要姓名和年龄,您应该使用.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 在他的回答中所做的那样,因为它不需要复制列表。
解决方案 4:
我认为指出哪些方法最快以及在什么情况下使用会很有趣:
以下是我在 2012 MacBook Pro 上运行的一些测试
def method1(dict, search_age):
for name, age in dict.iteritems():
if age == search_age:
return name
def method2(dict, search_age):
return [name for name,age in dict.iteritems() if age == search_age]
def method3(dict, search_age):
return dict.keys()[dict.values().index(search_age)]
profile.run()
每种方法执行 100,000 次的结果:
方法 1:
>>> profile.run("for i in range(0,100000): method1(dict, 16)")
200004 function calls in 1.173 seconds
方法 2:
>>> profile.run("for i in range(0,100000): method2(dict, 16)")
200004 function calls in 1.222 seconds
方法 3:
>>> profile.run("for i in range(0,100000): method3(dict, 16)")
400004 function calls in 2.125 seconds
因此,这表明对于小字典,方法 1 是最快的。这很可能是因为它返回第一个匹配项,而不是像方法 2 那样返回所有匹配项(参见下面的注释)。
有趣的是,对我拥有的包含 2700 个条目的字典执行相同的测试,我得到了完全不同的结果(这次运行 10,000 次):
方法 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()
)并将它们存储在内存中。
解决方案 5:
单行版本:(i 是旧词典,p 是反向词典)
解释:i.keys()
并i.values()
返回两个列表,分别包含字典的键和值。zip 函数可以将列表绑定在一起以生成字典。
p = dict(zip(i.values(),i.keys()))
警告:仅当值可散列且唯一时,此方法才会起作用。
解决方案 6:
我发现这个答案非常有效,但对我来说不太容易阅读。
为了更清楚,你可以反转字典的键和值。这样键就变成了值,值也变成了键,如下图所示。
mydict = {'george':16,'amber':19}
res = dict((v,k) for k,v in mydict.iteritems())
print(res[16]) # Prints george
或者对于 Python 3,(感谢@kkgarg)
mydict = {'george':16,'amber':19}
res = dict((v,k) for k,v in mydict.items())
print(res[16]) # Prints george
还
print(res.get(16)) # Prints george
这与其他答案基本相同。
解决方案 7:
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}
解决方案 8:
key = next((k for k in my_dict if my_dict[k] == val), None)
解决方案 9:
尝试用这一行代码来反转字典:
reversed_dictionary = dict(map(reversed, dictionary.items()))
解决方案 10:
如果您想通过值查找键,您可以使用字典推导来创建查找字典,然后使用它从值中查找键。
lookup = {value: key for key, value in self.data}
lookup[value]
解决方案 11:
我们可以通过Key
以下方式获得dict
:
def getKey(dct,value):
return [key for key in dct if (dct[key] == value)]
解决方案 12:
您可以使用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)]
解决方案 13:
以下是我对这个问题的看法。:) 我刚刚开始学习 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: * est.py (Thu Jun 06 05:10:02 2013)
Provide age: 19
amber 19
Garry 19
{'amber': 19, 'Garry': 19}
Execution Successful!
解决方案 14:
get_key = lambda v, d: next(k for k in d if d[k] is v)
解决方案 15:
使用列表推导的一行解决方案,如果值可能出现多次,则返回多个键。
[key for key,value in mydict.items() if value == 16]
解决方案 16:
考虑使用 Pandas。正如 William McKinney 的《Python 数据分析》中所述
另一种思考 Series 的方式是将其视为固定长度、有序的字典,因为它是索引值到数据值的映射。它可以在可能使用字典的许多情况下使用。
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)
解决方案 17:
d= {'george':16,'amber':19}
dict((v,k) for k,v in d.items()).get(16)
输出如下:
-> prints george
解决方案 18:
这里,recover_key 接受字典和要在字典中查找的值。然后我们循环遍历字典中的键,并与值的键进行比较,并返回该特定键。
def recover_key(dicty,value):
for a_key in dicty.keys():
if (dicty[a_key] == value):
return a_key
解决方案 19:
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
解决方案 20:
my_dict = {'A': 19, 'B': 28, 'carson': 28}
search_age = 28
只取一个
name = next((name for name, age in my_dict.items() if age == search_age), None)
print(name) # 'B'
获取多个数据
name_list = [name for name, age in filter(lambda item: item[1] == search_age, my_dict.items())]
print(name_list) # ['B', 'carson']
解决方案 21:
我浏览了所有答案,没有一个提到简单地使用列表理解?
这个 Pythonic单行解决方案可以返回任意数量的给定值的所有键(在 Python 3.9.1 中测试):
>>> dictionary = {'george' : 16, 'amber' : 19, 'frank': 19}
>>>
>>> age = 19
>>> name = [k for k in dictionary.keys() if dictionary[k] == age]; name
['george', 'frank']
>>>
>>> age = (16, 19)
>>> name = [k for k in dictionary.keys() if dictionary[k] in age]; name
['george', 'amber', 'frank']
>>>
>>> age = (22, 25)
>>> name = [k for k in dictionary.keys() if dictionary[k] in age]; name
[]
解决方案 22:
它已经得到解答,但是可以通过使用花哨的“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()))
解决方案 23:
我尝试阅读尽可能多的解决方案以避免给出重复的答案。但是,如果您正在处理一个字典,其值包含在列表中,并且如果您想获取具有特定元素的键,您可以这样做:
d = {'Adams': [18, 29, 30],
'Allen': [9, 27],
'Anderson': [24, 26],
'Bailey': [7, 30],
'Baker': [31, 7, 10, 19],
'Barnes': [22, 31, 10, 21],
'Bell': [2, 24, 17, 26]}
现在让我们找出值中包含 24 的名称。
for key in d.keys():
if 24 in d[key]:
print(key)
这也适用于多个值。
解决方案 24:
只是我的回答在lambda
和filter
。
filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age , dictionary )
解决方案 25:
这是一个有点奇怪的问题,因为第一条评论就提供了一个完美的答案。
根据提供的示例数据示例
dictionary = {'george': 16, 'amber': 19}
print(dictionary["george"])
它返回
16
因此,您希望对方
输入“16”并得到“george”,因此只需交换键和值,然后 presto
dictionary = {'george': 16, 'amber': 19}
inv_dict = {value:key for key, value in dictionary.items()}
print(inv_dict[16])
我的情况完全相反,因为我有一本字典
{16:'george', 19:'amber'}
我尝试喂“乔治”并得到 16...我尝试了几种循环和迭代器,都不错...它们有效,但这不是我会用来快速得到结果的简单的一行解决方案...所以我只是交换并找到了解决方案。
如果我遗漏了什么,请告诉我删除我的答案。
解决方案 26:
正如有人提到的那样,可能有多个键具有相同的值,如下my_dict
所示。此外,可能没有匹配的键。
my_dict ={'k1':1,'k2':2, 'k3':1, 'k4':12, 'k5':1, 'k6':1, 'k7':12}
这里有三种找到钥匙的方法,一种方法是最后一次击打,另外两种是第一次击打。
def find_last(search_value:int, d:dict):
return [x for x,y in d.items() if y==search_value].pop()
def find_first1(search_value:int, d:dict):
return next(filter(lambda x: d[x]==search_value, d.keys()), None)
def find_first2(search_value:int, d:dict):
return next(x for x,y in d.items() if y==search_value)
其中任何一个find_first1
都比其他的要快一点,并且None
在没有匹配的键的情况下将返回。
解决方案 27:
已经得到解答,但由于有几个人提到反转字典,这里介绍如何在一行中完成(假设 1:1 映射)以及一些各种性能数据:
蟒蛇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 uS vs. 以前情况下的最低 1.48 mS)。但是,对于列表末尾附近的较大偏移量,它的速度要慢得多(15.1ms vs. 相同的 1.48mS)。在我看来,低端的小幅节省不值得高端的成本。
解决方案 28:
Cat Plus Plus 提到,这不是字典的用途。原因如下:
字典的定义类似于数学中的映射。在这种情况下,字典是 K(键集)到 V(值)的映射 - 但反之则不然。如果取消引用字典,则期望返回一个值。但是,不同的键映射到同一个值是完全合法的,例如:
d = { k1 : v1, k2 : v2, k3 : v1}
当您通过其对应的值查找键时,您实际上是在反转字典。但映射不一定是可逆的!在此示例中,请求与 v1 对应的键可能会产生 k1 或 k3。您应该同时返回两者吗?只返回找到的第一个?这就是为什么 indexof() 对于字典未定义的原因。
如果您了解数据,则可以执行此操作。但是 API 不能假设任意字典都是可逆的,因此缺少这样的操作。
解决方案 29:
这是我的看法。这有利于显示多个结果,以防万一你需要一个。所以我也添加了列表
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)
就是这样...
解决方案 30:
通过“查找”值来查找列表中的键并不容易。但是,如果您知道值,则可以通过遍历键来查找字典中的元素值。如果 D[element](其中 D 是字典对象)等于您要查找的键,则可以执行一些代码。
D = {'Ali': 20, 'Marina': 12, 'George':16}
age = int(input('enter age: '))
for element in D.keys():
if D[element] == age:
print(element)
扫码咨询,免费领取项目管理大礼包!