Pythonic way to access arbitrary element from dictionary

后端 未结 4 771
萌比男神i
萌比男神i 2020-12-06 16:33

I have a dictionary, full of items. I want to peek at a single, arbitrary item:

print("Amongst our dictionary\'s items are such diverse elements as: %s&q         


        
相关标签:
4条回答
  • 2020-12-06 16:52

    I believe the question has been significantly answered but hopefully this comparison will shed some light on the clean code vs time trade off:

    from timeit import timeit
    from random import choice
    A = {x:[y for y in range(100)] for x in range(1000)}
    def test_pop():
        k, v= A.popitem()
        A[k] = v
    
    def test_iter(): k = next(A.iterkeys())
    
    def test_list(): k = choice(A.keys())
    
    def test_insert(): A[0] = 0
    
    if __name__ == '__main__':
        print('pop', timeit("test_pop()", setup="from __main__ import test_pop", number=10000))
        print('iter', timeit("test_iter()", setup="from __main__ import test_iter", number=10000))
        print('list', timeit("test_list()", setup="from __main__ import test_list", number=10000))
        print('insert', timeit("test_insert()", setup="from __main__ import test_insert", number=10000))
    

    Here are the results:

    ('pop', 0.0021750926971435547)
    ('iter', 0.002003908157348633)
    ('list', 0.047267913818359375)
    ('insert', 0.0010859966278076172)
    

    It seems that using iterkeys is only marginal faster then poping an item and re-inserting but 10x's faster then creating the list and choosing a random object from it.

    0 讨论(0)
  • 2020-12-06 16:53

    Why not use random?

    import random
    
    def arb(dictionary):
        return random.choice(dictionary.values())
    

    This makes it very clear that the result is meant to be purely arbitrary and not an implementation side-effect. Until performance becomes an actual issue, always go with clarity over speed.

    It's a shame that dict_values don't support indexing, it'd be nice to be able to pass in the value view instead.

    Update: since everyone is so obsessed with performance, the above function takes <120ms to return a random value from a dict of 1 million items. Relying on clear code is not the amazing performance hit it's being made out to be.

    0 讨论(0)
  • 2020-12-06 16:56

    Avoiding the whole values/itervalues/viewvalues mess, this works equally well in Python2 or Python3

    dictionary[next(iter(dictionary))]
    

    alternatively if you prefer generator expressions

    next(dictionary[x] for x in dictionary)
    
    0 讨论(0)
  • 2020-12-06 17:01

    Similar to your second solution, but slightly more obvious, in my opinion:

    return next(iter(dictionary.values()))
    

    This works in python 2 as well as in python 3, but in python 2 it's more efficient to do it like this:

    return next(dictionary.itervalues())
    
    0 讨论(0)
提交回复
热议问题