I made a function which will look up ages in a Dictionary
and show the matching name:
dictionary = {\'george\' : 16, \'amber\' : 19}
search_age
Just my answer in lambda
and filter
.
filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age , dictionary )
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.
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.
p = dict(zip(i.values(),i.keys()))
Warning : This will work only if the values are hashable and unique.
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)
d= {'george':16,'amber':19}
dict((v,k) for k,v in d.items()).get(16)
The output is as follows:
-> prints george
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...