By user998316


2011-11-05 21:09:18 8 Comments

I made a function which will look up ages in a Dictionary and show the matching name:

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

I know how to compare and find the age I just don't know how to show the name of the person. Additionally, I am getting a KeyError because of line 5. I know it's not correct but I can't figure out how to make it search backwards.

30 comments

@Bishwas Mishra 2019-01-25 05:59:25

Just my answer in lambda and filter.

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age  , dictionary )

@cyber-math 2019-01-15 03:12:36

I tried to read as many solutions as I can to prevent giving duplicate answer. However, if you are working on a dictionary which values are contained in lists and if you want to get keys that have a particular element you could do this:

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]}

Now lets find names that have 24 in their values.

for key in d.keys():    
    if 24 in d[key]:
        print(key)

This would work with multiple values as well.

@Cat Plus Plus 2011-11-05 21:13:09

There is none. dict is not intended to be used this way.

for name, age in dictionary.items():    # for name, age in dictionary.iteritems():  (for Python 2.x)
    if age == search_age:
        print(name)

@Yuriy Petrovskiy 2016-08-24 17:53:24

In Python 3.x list.items() instead of list.iteritems() should be used

@Louis Maddox 2016-10-13 13:20:55

I don't agree... agf's answer below is more constructive. A perfectly reasonable use case is not "unintended" (list comprehension fits such a use case anyway). A dict can be for multiple things at different times; keys and values have a clear meaning, of course, but "dict items with a given value" is a perfectly reasonable request. The recommendation to use a list of pairs would discard the context that one item is a 'definition' from the other, e.g. in parameter lists...

@johnaphun 2018-08-05 14:34:04

Try this one-liner to reverse a dictionary:

reversed_dictionary = dict(map(reversed, dictionary.items()))

@pyd 2018-11-02 05:17:25

how this will work when the value is a list

@fanny 2013-10-03 18:01:04

one line version: (i is an old dictionary, p is a reversed dictionary)

explanation : i.keys() and i.values() returns two lists with keys and values of the dictionary respectively. The zip function has the ability to tie together lists to produce a dictionary.

warning : This would work only if the values are hashable and unique.

p = dict(zip(i.values(),i.keys()))

@The Unfun Cat 2013-10-25 07:52:04

@gregorySalvan 2014-05-20 03:20:28

this work only when values are hashable.

@ely 2014-05-22 19:49:18

... and when there are no duplicate values.

@John Strong 2017-02-10 17:10:34

Beautiful. W.r.t the comment above, of course it only works when there are no duplicate values, but then, the question that started this thread makes the assumption that we have a one-to-one function, so given that assumption, this is the most elegant response by far.

@muon 2018-07-12 15:31:05

expanding on hashable values: if your values are lists/sets convert them to tuple for this to work (they still need to be unique).

@Rafael Valero 2018-05-08 11:50:43

I found this answer very effective but still no very easy to read for me.

To make it more clear you can invert the key and the value of a dictionary. This is make the keys values and the values keys, as seen here.

mydict = {'george':16,'amber':19}
res = dict((v,k) for k,v in mydict.iteritems())
print(res[16]) # Prints george

or

mydict = {'george':16,'amber':19}
dict((v,k) for k,v in mydict.iteritems())[16]

which is essentially the same that this other answer.

@Cesar 2018-04-20 13:31:21

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.

For multiple occurrences use:

keys = [filter( lambda x: dictionary[x] == k  , dictionary )]

@Bishwas Mishra 2019-01-25 05:55:44

*** NameError: global name 'dictionary' is not defined

@Bishwas Mishra 2019-01-25 05:58:30

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age , dictionary )

@Sakhri Houssem 2018-03-18 22:03:34

we can get the Key of dict by :

def getKey(dict,value):
     return [key for key in dict.keys() if (dict[key] == value)]

@Brett 2017-11-26 06:44:56

get_key = lambda v, d: next(k for k in d if d[k] is v)

@shishir 2015-09-20 05:07:32

Here, recover_key takes dictionary and value to find in dictionary. We then loop over the keys in dictionary and make a comparison with that of value and return that particular key.

def recover_key(dicty,value):
    for a_key in dicty.keys():
        if (dicty[a_key] == value):
            return a_key

@Ajean 2015-09-26 00:13:12

Good answers explain as well as provide code. Consider updating your answer to include an explanation about how this code works and why it is the best option.

@Axel 2017-08-18 17:11:46

Consider using Pandas. As stated in William McKinney's "Python for Data Analysis'

Another way to think about a Series is as a fixed-length, ordered dict, as it is a mapping of index values to data values. It can be used in many contexts where you might use a dict.

import pandas as pd
list = {'george':16,'amber':19}
lookup_list = pd.Series(list)

To query your series do the following:

lookup_list[lookup_list.values == 19]

Which yields:

Out[1]: 
amber    19
dtype: int64

If you need to do anything else with the output transforming the answer into a list might be useful:

answer = lookup_list[lookup_list.values == 19].index
answer = pd.Index.tolist(answer)

@tmthyjames 2018-06-08 13:02:55

Who's William McKinney?

@Axel 2019-02-07 19:14:03

He's the creator of pandas. He's more commonly known as Wes, though.

@Meilin He 2017-07-27 22:43:43

A simple way to do this could be:

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

This will return a list of the keys with value that match search_age. You can also replace "list==search_age" with any other conditions statement if needed.

@Nat 2017-07-07 13:43:45

I hope this might help...

for key in list:
   if list[key] == search_value:
       return key

@fr1eza 2017-07-02 12:59:21

I know this is old but you could quite easily find all the people in the list with your search age using list comprehension.

ages = {'george':16,'amber':19}
search = 16
print([name for (name, age) in ages.items() if age == search])

@Jelen 2016-07-26 10:48:30

a = {'a':1,'b':2,'c':3}
{v:k for k, v in a.items()}[1]

or better

{k:v for k, v in a.items() if v == 1}

@7H3 IN5ID3R 2016-12-18 22:37:18

What if there is another key which holds the same value of a? May be pythonic way. But not a good idea.

@Jelen 2017-04-21 13:03:03

good point, i added solution which works with nonunique values

@Andriy Ivaneyko 2016-03-07 06:52:16

You can get key by using dict.keys(), dict.values() and list.index() methods, see code samples below:

names_dict = {'george':16,'amber':19}
search_age = int(raw_input("Provide age"))
key = names_dict.keys()[names_dict.values().index(search_age)]

@Andersson 2016-04-06 11:04:07

you don't use defined search_age var on next line... Maybe you should replace value with search_age?

@Blue_Elephant 2017-08-11 12:21:41

I get this error: 'dict_values' object has no attribute 'index'

@Andriy Ivaneyko 2017-08-11 16:05:11

@Blue_Elephant could you please provide code snippet you've got error and python version ( also print of type(dict_values) would be useful ) ?

@Raj Damani 2016-03-07 06:41:10

def get_Value(dic,value):
    for name in dic:
        if dic[name] == value:
            del dic[name]
            return name

@Hamid FzM 2015-09-06 17:54:20

You need to use a dictionary and reverse of that dictionary. It means you need another data structure. If you are in python 3, use enum module but if you are using python 2.7 use enum34 which is back ported for python 2.

Example:

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 

@Surest Texas 2015-07-01 23:16:32

This is how you access the dictionary to do what you want:

list = {'george': 16, 'amber': 19}
search_age = raw_input("Provide age")
for age in list:
    if list[age] == search_age:
        print age

of course, your names are so off it looks like it would be printing an age, but it DOES print the name. Since you are accessing by name, it becomes more understandable if you write:

list = {'george': 16, 'amber': 19}
search_age = raw_input("Provide age")
for name in list:
    if list[name] == search_age:
        print name

Better yet:

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

@Ethan 2014-11-11 20:45:42

There is no easy way to find a key in a list by 'looking up' the value. However, if you know the value, iterating through the keys, you can look up values in the dictionary by the element. If D[element] where D is a dictionary object, is equal to the key you're trying to look up, you can execute some code.

D = {'Ali': 20, 'Marina': 12, 'George':16}
age = int(input('enter age:\t'))  
for element in D.keys():
    if D[element] == age:
        print(element)

@Stênio Elson 2012-10-31 00:56:34

mydict = {'george':16,'amber':19}
print mydict.keys()[mydict.values().index(16)] # Prints george

Or in Python 3.x:

mydict = {'george':16,'amber':19}
print(list(mydict.keys())[list(mydict.values()).index(16)]) # Prints george

Basically, it separates the dictionary's values in a list, finds the position of the value you have, and gets the key at that position.

More about keys() and .values() in Python 3: Python: simplest way to get list of values from dict?

@iskorum 2013-09-23 14:01:17

Looks great but is it works always? I mean, do list.keys() and list.values() functions generate items in same order?

@Veedrac 2013-09-25 23:21:57

Yes, they are guaranteed to be consistent. Additionally order is guaranteed not to change through iterations as long as the dictionary is not modified.

@sinekonata 2013-11-29 01:24:26

Wow, you got it, that's exactly what I wanted. Something that doesn't loop for nothing. Thanks for the elegant solution.

@James Sapam 2013-12-13 13:17:32

This looks to be a good solution but index gave only one value right, so if you ve multiple equal values, then it should return multiple keys right ?

@deeshank 2014-11-17 10:09:14

The keys() may not be ordered as per the values() always

@ArtOfWarfare 2015-08-06 18:04:19

@Veedrac - Do you have any proof to backup your statement?

@Veedrac 2015-08-06 19:14:42

@ArtOfWarfare docs.python.org/3/library/stdtypes.html#dict-views, "If keys, values and items views are iterated over with no intervening modifications to the dictionary, the order of items will directly correspond."

@ArtOfWarfare 2015-08-06 19:30:21

@Veedrac - Very nice, thank you. I checked the same section of the documentation and it also applies to 2.7. The promise is still there in 2.6, although phrased slightly differently... it sounds like in 2.6 the promise only applied to CPython, not other Python implementations.

@DaveL17 2016-02-02 13:22:41

This solution worked nicely for me in an instance where I knew only one key could have the value in question, however, if multiple values exist, it will return one of them. (P 2.6)

@user2357112 2016-04-27 23:47:44

@sinekonata: It still performs an expensive loop under the hood; the loop is just hidden inside the index method.

@sinekonata 2016-10-10 17:42:21

@user2357112 Yes I realized that immediately after writing it but I wasn't certain of it and at any rate it's still likely much more efficient.

@Amit Upadhyay 2017-02-12 10:03:36

@iskorum yes, it will always work. even I too had same doubt but after reading this - stackoverflow.com/questions/15479928/… everything becomes clear.

@JMJ 2018-06-04 21:13:31

It's an elegant way but a question: what if the values are unique but still includes my 'keyword'. imagine a dict with 'order' and 'suborder' values and I'm looking for 'order' by searching in dict.values(). Do I get the relevant key by using ur method or either of them?

@Andres 2018-11-26 03:02:21

mydict = {'george':16,'amber':19} age = '16' dict(list(zip(mydict.values(),mydict)))[age]

@alancalvitti 2019-01-07 16:27:50

As per Dannid's comment in another answer below, mydict = {'george':16,'amber':19, "stenio":16} does not return "stenio"

@Safia Abdalla 2014-12-18 18:37:30

If you want to find the key by the value, you can use a dictionary comprehension to create a lookup dictionary and then use that to find the key from the value.

lookup = {value: key for key, value in self.data}
lookup[value]

@Dima Tisnek 2017-01-20 20:36:18

A clarification could be added when this would and wouldn't work...

@eold 2014-10-17 17:53:25

Here is a solution which works both in Python 2 and Python 3:

dict((v, k) for k, v in list.items())[search_age]

The part until [search_age] constructs the reverse dictionary (where values are keys and vice-versa). You could create a helper method which will cache this reversed dictionary like so:

def find_name(age, _rev_lookup=dict((v, k) for k, v in ages_by_name.items())):
    return _rev_lookup[age]

or even more generally a factory which would create a by-age name lookup method for one or more of you lists

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]

so you would be able to do:

find_teen_by_age = create_name_finder({'george':16,'amber':19})
...
find_teen_by_age(search_age)

Note that I renamed list to ages_by_name since the former is a predefined type.

@Jeroen 2014-06-03 09:55:55

d= {'george':16,'amber':19}

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

The output is as follows:

-> prints george

@auro 2017-02-07 21:00:33

[k for k, v in d.items() if v==16]

@wzbozon 2014-08-24 18:13:12

Sometimes int() may be needed:

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

@user3649211 2014-05-18 08:21:02

here is my take on it. This is good for displaying multiple results just in case you need one. So I added the list as well

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)

And that's it...

@Dan Ahlquist 2014-03-27 21:38:21

Cat Plus Plus mentioned that this isn't how a dictionary is intended to be used. Here's why:

The definition of a dictionary is analogous to that of a mapping in mathematics. In this case, a dict is a mapping of K (the set of keys) to V (the values) - but not vice versa. If you dereference a dict, you expect to get exactly one value returned. But, it is perfectly legal for different keys to map onto the same value, e.g.:

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

When you look up a key by it's corresponding value, you're essentially inverting the dictionary. But a mapping isn't necessarily invertible! In this example, asking for the key corresponding to v1 could yield k1 or k3. Should you return both? Just the first one found? That's why indexof() is undefined for dictionaries.

If you know your data, you could do this. But an API can't assume that an arbitrary dictionary is invertible, hence the lack of such an operation.

@Corley Brigman 2013-10-03 18:52:29

already been answered, but since several people mentioned reversing the dictionary, here's how you do it in one line (assuming 1:1 mapping) and some various perf data:

python 2.6:

reversedict = dict([(value, key) for key, value in mydict.iteritems()])

2.7+:

reversedict = {value:key for key, value in mydict.iteritems()}

if you think it's not 1:1, you can still create a reasonable reverse mapping with a couple lines:

reversedict = defaultdict(list)
[reversedict[value].append(key) for key, value in mydict.iteritems()]

how slow is this: slower than a simple search, but not nearly as slow as you'd think - on a 'straight' 100000 entry dictionary, a 'fast' search (i.e. looking for a value that should be early in the keys) was about 10x faster than reversing the entire dictionary, and a 'slow' search (towards the end) about 4-5x faster. So after at most about 10 lookups, it's paid for itself.

the second version (with lists per item) takes about 2.5x as long as the simple version.

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

Also had some interesting results with ifilter. Theoretically, ifilter should be faster, in that we can use itervalues() and possibly not have to create/go through the entire values list. In practice, the results were... odd...

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

So, for small offsets, it was dramatically faster than any previous version (2.36 *u*S vs. a minimum of 1.48 *m*S for previous cases). However, for large offsets near the end of the list, it was dramatically slower (15.1ms vs. the same 1.48mS). The small savings at the low end is not worth the cost at the high end, imho.

@slashdottir 2014-01-23 22:53:07

I so much want this (reversedict = defaultdict(list) reversedict[value].append(key) for key, value in largedict.iteritems()] ) to work, but using Python 2.7.3, I get syntax error on the word 'for'

@Corley Brigman 2014-01-23 23:37:10

is that what you actually typed? you're missing a [ in it, if it is. otherwise, make sure it's on two lines, or put a ; between them if it's not.

@slashdottir 2014-01-24 15:30:41

argh.. you're right. can't believe I missed that bracket. eh. sorry. brain broken

@Deithrian 2013-06-06 02:17:35

Here is my take on this problem. :) I have just started learning Python, so I call this:

"The Understandable for beginners" solution.

#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!

@formiaczek 2013-05-30 23:08:25

it's answered, but it could be done with a fancy 'map/reduce' use, e.g.:

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()))

Related Questions

Sponsored Content

42 Answered Questions

[SOLVED] How do I sort a dictionary by value?

43 Answered Questions

[SOLVED] How to merge two dictionaries in a single expression?

13 Answered Questions

[SOLVED] Iterating over dictionaries using 'for' loops

19 Answered Questions

21 Answered Questions

[SOLVED] Check if a given key already exists in a dictionary

  • 2009-10-21 19:05:09
  • Mohan Gulati
  • 2724488 View
  • 2583 Score
  • 21 Answer
  • Tags:   python dictionary

14 Answered Questions

[SOLVED] Add new keys to a dictionary?

  • 2009-06-21 22:07:39
  • lfaraone
  • 2815953 View
  • 2171 Score
  • 14 Answer
  • Tags:   python dictionary

49 Answered Questions

[SOLVED] Sort a Map<Key, Value> by values

26 Answered Questions

[SOLVED] What is the best way to iterate over a dictionary?

  • 2008-09-26 18:20:06
  • Jake Stewart
  • 1312974 View
  • 2199 Score
  • 26 Answer
  • Tags:   c# dictionary loops

8 Answered Questions

[SOLVED] How to remove a key from a Python dictionary?

20 Answered Questions

[SOLVED] Getting key with maximum value in dictionary?

Sponsored Content