我创建了一个函数,它会在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
我知道如何比较和找到我只是不知道如何显示这个人姓名的年龄。另外,由于第5行,我得到KeyError
。我知道这不正确,但我无法弄清楚如何向后搜索。
答案 0 :(得分:482)
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()
和.values()
的更多信息:Python: simplest way to get list of values from dict?
答案 1 :(得分:448)
没有。 dict
不打算以这种方式使用。
for name, age in dictionary.items(): # for name, age in dictionary.iteritems(): (for Python 2.x)
if age == search_age:
print(name)
答案 2 :(得分:215)
如果您希望名称和都是年龄,那么您应该使用.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
是内置类型的名称,您不应该将该名称用于其他任何内容。< / p>
您甚至可以在一行中获得具有给定年龄的所有人的列表:
[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在他的回答中做了,因为它没有不需要复制清单。
答案 3 :(得分:61)
我认为有必要指出哪种方法最快,以及在什么情况下:
这是我跑过的一些测试(在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 很多更快。只是表明你的dict的大小会影响你选择哪种方法。
注意: 方法2返回所有名称的列表,而方法1和3仅返回第一个匹配。 我没有考虑内存使用情况。我不确定方法3是否创建了2个额外的列表(keys()和values())并将它们存储在内存中。
答案 4 :(得分:41)
一行版本:(我是旧词典,p是反向词典)
说明:i.keys()和i.values()分别返回两个包含字典的键和值的列表。 zip函数可以将列表绑定在一起以生成字典。
警告:仅当值具有可清除且唯一时才会起作用。
p = dict(zip(i.values(),i.keys()))
答案 5 :(得分:23)
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}
答案 6 :(得分:19)
lKey = [key for key, value in lDictionary.iteritems() if value == lValue][0]
答案 7 :(得分: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)]
答案 8 :(得分:9)
如果要按值查找键,可以使用字典理解创建查找字典,然后使用该字典从值中查找键。
lookup = {value: key for key, value in self.data}
lookup[value]
答案 9 :(得分:9)
尝试以下一种方法来反转字典:
import moment = require('moment');
console.log(moment().format('LLLL'));
答案 10 :(得分:9)
以下是我对此问题的看法。 :) 我刚开始学习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!
答案 11 :(得分:7)
我发现这个answer非常有效,但对我来说仍然不容易阅读。
为了使其更清晰,您可以反转键和字典的值。这是键值和值键,如here所示。
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]
与其他answer基本相同。
答案 12 :(得分:6)
考虑使用熊猫。正如William McKinney的“用于数据分析的Python”
所述考虑系列的另一种方式是定长,有序 dict,因为它是索引值到数据值的映射。有可能 在很多情况下都可以使用dict。
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)
答案 13 :(得分:6)
这里,recover_key需要字典和值才能在字典中查找。然后我们遍历字典中的键并与值进行比较并返回该特定键。
def recover_key(dicty,value):
for a_key in dicty.keys():
if (dicty[a_key] == value):
return a_key
答案 14 :(得分:5)
get_key = lambda v, d: next(k for k in d if d[k] is v)
答案 15 :(得分:5)
我瞥见了所有答案,但没有提到仅使用列表理解?
这个 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
[]
答案 16 :(得分:4)
我知道这已经过时了,但您可以使用列表理解轻松找到列表中所有搜索年龄的人。
ages = {'george':16,'amber':19}
search = 16
print([name for (name, age) in ages.items() if age == search])
答案 17 :(得分:4)
def get_Value(dic,value):
for name in dic:
if dic[name] == value:
del dic[name]
return name
答案 18 :(得分:4)
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
答案 19 :(得分:4)
它得到了回答,但可以使用花哨的'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()))
答案 20 :(得分:3)
通过查找&#39;找不到列表中的密钥是没有简单的方法。价值。但是,如果您知道该值,则遍历键,您可以通过元素在字典中查找值。如果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)
答案 21 :(得分:3)
我希望这可能会有所帮助......
for key in list:
if list[key] == search_value:
return key
答案 22 :(得分:3)
这是我的看法。这对于显示多个结果非常有用,以防您需要。所以我也添加了列表
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)
那就是......
答案 23 :(得分:2)
这是一个奇怪的问题,因为第一条评论提供了完美的答案。
基于提供的样本数据示例
dictionary = {'george': 16, 'amber': 19}
print(dictionary["george"])
它回来了
16
所以你想要相反的
输入“16”并得到“乔治”
所以只需交换键、值和 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 ……我尝试了几种循环和迭代器,它们还可以……它们可以工作,但这不是我用来快速获得结果的简单的单行解决方案。 ..所以我只是交换并找到了解决方案。
如果我错过了什么,请告诉我删除我的答案。
答案 24 :(得分:2)
有时可能需要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
答案 25 :(得分:2)
d= {'george':16,'amber':19}
dict((v,k) for k,v in d.items()).get(16)
输出如下:
-> prints george
答案 26 :(得分:2)
Cat Plus Plus提到这不是字典的使用方式。原因如下:
字典的定义类似于数学中的映射。在这种情况下,dict是K(键组)到V(值)的映射 - 但反之亦然。如果你取消引用dict,你希望得到一个返回的值。但是,将不同的键映射到相同的值是完全合法的,例如:
d = { k1 : v1, k2 : v2, k3 : v1}
当你通过它的相应值查找一个键时,你实际上是在反转字典。但是映射不一定是可逆的!在该示例中,要求对应于v1的密钥可以产生k1或k3。你应该两个回来吗?刚发现的第一个?这就是为词典定义indexof()的原因。
如果您知道自己的数据,就可以这样做。但是API不能假设任意字典是可逆的,因此缺少这样的操作。
答案 27 :(得分:2)
您需要使用字典并反转该字典。这意味着您需要另一种数据结构。如果您使用的是python 3,请使用enum
模块,但如果您使用的是python 2.7,请使用enum34
替换为python 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
答案 28 :(得分:2)
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']
答案 29 :(得分:1)
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 )]
答案 30 :(得分:1)
这是一个真正的“可逆字典”,基于 Adam Acosta 的解决方案,但强制 val-to-key 调用是唯一的,并且可以轻松地从值中返回键:
from collections import UserDict
class ReversibleDict(UserDict):
def __init__(self, enforce_unique=True, *args, **kwargs):
super().__init__(*args, **kwargs)
self.val_to_keys = {}
self.check_val = self.check_unique if enforce_unique else lambda x: x
def __setitem__(self, key, value):
self.check_val(value)
super().__setitem__(key, value)
self.val_to_keys[value] = key
def __call__(self, value):
return self.val_to_keys[value]
def check_unique(self, value):
assert value not in self.val_to_keys, f"Non unique value '{value}'"
return value
如果你想强制字典值的唯一性,确保设置enforce_unique=True。从值中获取键只需执行 rev_dict(value),从键中调用值就像往常一样 dict['key'],这是一个用法示例:
rev_dict = ReversibleDict(enforce_unique=True)
rev_dict["a"] = 1
rev_dict["b"] = 2
rev_dict["c"] = 3
print("full dictinoary is: ", rev_dict)
print("value for key 'b' is: ", rev_dict["b"])
print("key for value '2' is: ", rev_dict(2))
print("tring to set another key with the same value results in error: ")
rev_dict["d"] = 1
答案 31 :(得分:1)
我意识到已经很长时间了,最初的提问者可能不再需要任何答案,但是如果您确实可以控制此代码,那么这些都不是好的答案。您只是使用了错误的数据结构。这是双向 dict 用例的完美说明:
>>> from collections import defaultdict, UserDict
>>> class TwoWayDict(UserDict):
... def __init__(self, *args, **kwargs):
... super().__init__(*args, **kwargs)
... self.val_to_keys = defaultdict(list)
... def __setitem__(self, key, value):
... super().__setitem__(key, value)
... self.val_to_keys[value].append(key)
... def get_keys_for_val(self, value):
... return self.val_to_keys[value]
...
>>> d = TwoWayDict()
>>> d['a'] = 1
>>> d['b'] = 1
>>> d.get_keys_for_val(1)
['a', 'b']
为插入增加了微不足道的开销,但您保持恒定时间查找,除了现在在两个方向上。无需每次需要时从头开始构建反向映射。只需随时存储并根据需要访问它。
此外,其中许多答案甚至都不正确,因为很明显,许多人可能有相同的年龄,但他们只返回第一个匹配的键,而不是全部。
答案 32 :(得分:1)
我尝试阅读尽可能多的解决方案,以防止给出重复的答案。但是,如果您正在使用字典,其值包含在列表中,并且想要获取具有特定元素的键,则可以执行以下操作:
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)
这同样适用于多个值。
答案 33 :(得分:1)
已经得到了解答,但由于有几个人提到了翻译字典,这里是你如何在一行(假设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)。然而,对于靠近列表末尾的大偏移量,它显着变慢(相对于相同的1.48mS,为15.1ms)。低端的小额节省不值得高端的成本,imho。
答案 34 :(得分:1)
我们可以通过以下方式获取Key
dict
def getKey(dict,value):
return [key for key in dict.keys() if (dict[key] == value)]
答案 35 :(得分:1)
这是您访问字典以执行所需操作的方式:
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
答案 36 :(得分:0)
只有我在lambda
和filter
中的回答。
filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age , dictionary )
答案 37 :(得分:0)
在我的情况下,最简单的方法是在代码中实例化自变量,然后可以像下面这样从中调用键
这是我上课的字典
class Config:
def local(self):
return {
"temp_dir": "/tmp/dirtest/",
"devops": "Mansur",
}
实例化字典
config = vars.Config()
local_config = config.local()
最后调用您的字典键
patched = local_config.get("devops")
答案 38 :(得分:0)
我最终用一个函数来完成它。这样,您可以避免执行完整循环,并且 intuition 表示它应该比提出的其他解决方案更快。
def get_key_from_value(my_dict, to_find):
for k,v in my_dict.items():
if v==to_find: return k
return None
答案 39 :(得分:0)
这是一个适用于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)
请注意,我将list
重命名为ages_by_name
,因为前者是预定义类型。
答案 40 :(得分:-1)
执行此操作的简单方法可能是:
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匹配的键列表。您也可以替换&#34; list == search_age&#34;如果需要,可以使用任何其他条件声明。