Get key by value in dictionary

后端 未结 30 2189
北恋
北恋 2020-11-21 06:28

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

dictionary = {\'george\' : 16, \'amber\' : 19}
search_age          


        
相关标签:
30条回答
  • 2020-11-21 07:02

    Just my answer in lambda and filter.

    filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age  , dictionary )
    
    0 讨论(0)
  • 2020-11-21 07:02

    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.

    0 讨论(0)
  • 2020-11-21 07: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.

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

    Warning : This will work only if the values are hashable and unique.

    0 讨论(0)
  • 2020-11-21 07:04

    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)
    
    0 讨论(0)
  • 2020-11-21 07:04
    d= {'george':16,'amber':19}
    
    dict((v,k) for k,v in d.items()).get(16)
    

    The output is as follows:

    -> prints george
    
    0 讨论(0)
  • 2020-11-21 07:04

    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...

    0 讨论(0)
提交回复
热议问题