Получить ключ по значению в словаре - PullRequest
516 голосов
/ 06 ноября 2011

Я сделал функцию, которая будет искать возраст в 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. Я знаю, что это не правильно, но я не могу понять, как заставить его искать в обратном направлении.

Ответы [ 34 ]

3 голосов
/ 11 ноября 2014

Нет простого способа найти ключ в списке путем «поиска» значения. Однако, если вы знаете значение, перебирая ключи, вы можете искать значения в словаре по элементу. Если 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)
3 голосов
/ 18 мая 2014

вот мой взгляд на это.Это хорошо для отображения нескольких результатов на тот случай, если вам нужен один из них.Так что я добавил список также

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)

И это все ...

2 голосов
/ 28 марта 2014

Cat Plus Plus отметил, что это не то, как словарь предназначен для использования. И вот почему:

Определение словаря аналогично определению в математике. В этом случае dict - это отображение K (набора ключей) на V (значения), но не наоборот. Если вы разыменуете dict, вы ожидаете получить ровно одно возвращаемое значение. Но вполне допустимо, чтобы разные ключи отображались на одно и то же значение, например ::100100

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

Когда вы ищите ключ по соответствующему значению, вы, по сути, инвертируете словарь. Но отображение не обязательно обратимо! В этом примере запрос ключа, соответствующего v1, может привести к k1 или k3. Вы должны вернуть оба? Только первый найден? Вот почему indexof () не определяется для словарей.

Если вы знаете свои данные, вы можете сделать это. Но API не может предположить, что произвольный словарь обратим, отсюда и отсутствие такой операции.

2 голосов
/ 24 августа 2014

Иногда может понадобиться 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
2 голосов
/ 03 июня 2014
d= {'george':16,'amber':19}

dict((v,k) for k,v in d.items()).get(16)

Вывод выглядит следующим образом:

-> prints george
2 голосов
/ 06 сентября 2015

Вам нужно использовать словарь и наоборот этого словаря. Это означает, что вам нужна другая структура данных. Если вы используете 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 
1 голос
/ 20 апреля 2018
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 )]
1 голос
/ 19 марта 2018

мы можем получить Key из dict по:

def getKey(dict,value):
     return [key for key in dict.keys() if (dict[key] == value)]
1 голос
/ 03 октября 2013

уже получен ответ, но так как несколько человек упомянули обратный ход словаря, вот как вы делаете это в одну строку (при условии отображения 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 для предыдущих случаев). Однако, для больших смещений в конце списка, он был значительно медленнее (15,1 мс против тех же 1,48 мс). Небольшая экономия на нижнем конце не стоит затрат на верхнем, imho.

1 голос
/ 25 января 2019

Только мой ответ в lambda и filter.

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age  , dictionary )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...