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