2
NAMES  =  ['Alice', 'Bob','Cathy','Dan','Ed','Frank',
           'Gary','Helen','Irene','Jack', 'Kelly','Larry'] 
AGES  =  [20,21,18,18,19,20,20,19,19,19,22,19]

def nameage(a,b):
    nameagelist = [x for x in zip(a,b)]
    nameagedict = dict(nameagelist)

    return nameagedict

def name(a):
    for x in nameage(NAMES,AGES):
        if a in nameage(NAMES,AGES).values():
            print nameage(NAMES,AGES).keys()

print name(19)

I am trying to return the names of the people aged 19. How do I search the dictionary by value and return the key?

MPelletier
  • 16,256
  • 15
  • 86
  • 137
super9
  • 29,181
  • 39
  • 119
  • 172
  • Your example data does not match your question. You start with two lists, not a dictionary. If your data starts in the type of a dict where key = name and value = age, do a reverse dictionary lookup: Some discussion here http://stackoverflow.com/questions/2568673/inverse-dictionary-lookup-python#2568673 – DevPlayer Jul 24 '15 at 01:37
  • Also your function named "name" is misleading. Perhaps it should be named "names" as there are multiple names for most ages. Also, your data implies a potential problem. Even though the actual data may not be people's names nor people's ages, in data of any size both objects are very likely not unique. In your example there could often be more then one John Smith born on a certain day. – DevPlayer Jul 24 '15 at 01:43

3 Answers3

9
print [key for (key,value) in nameagedict.items() if value == 19]

nameagedict.items() gives you a list of all items in the dictionary, as (key,value) tuples.

payne
  • 13,833
  • 5
  • 42
  • 49
0

I had a similar problem. Here's my solution which returns the keys and values as an array of tuples.

filter(lambda (k,v): v==19, nameagedict.items())
  • What I actually need is a reverse-lookup dictionary. Of course, this only works when Key:value is a 1 to 1 relationship (never 1 to many). `dict(map(lambda (k,v): (v,k), {1:2, 3:4, 5:6}.items()))` – UltramaticOrange Nov 06 '13 at 20:05
0

Partial solution

names = {age:sorted([name for index,name in enumerate(NAMES) if age == AGES[index]]) for age in sorted(set(AGES))}
print(names)

Returns:

{18: ['Cathy', 'Dan'], 19: ['Ed', 'Helen', 'Irene', 'Jack', 'Larry'], 20: ['Alice', 'Frank', 'Gary'], 21: ['Bob'], 22: ['Kelly']}

Leave out sorted() if you wish. You could also add count() so the data returned something like

{18: [('Cathy',3), ('Dan',7), ...} 

if there were 3 Cathys and 7 Dans.

Although the above looks short I suspect an actual for loop would iterate over the original lists less.

Or even better:

def names(age):
    index = 0
    while index < len(AGES):
        if AGES[index] == age:
            yield NAMES[index]
        index += 1

print('19 year olds')
for name in names(19):
    print(name)
DevPlayer
  • 5,393
  • 1
  • 25
  • 20