根据字典中的值获取键

2024-11-25 08:49:00
admin
原创
216
摘要:问题描述:我创建了一个函数,它可以查找年龄Dictionary并显示匹配的名称:dictionary = {'george' : 16, 'amber' : 19} search_age = raw_input("Provide age") for age in dictionary.va...

问题描述:

我创建了一个函数,它可以查找年龄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:

只是我的回答在lambdafilter

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)
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3892  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2717  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   52  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   54  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   49  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用