Pythonic way to access an arbitrary element from a dictionary

I have a dictionary full of subjects. I want to peek at one, arbitrary element:

print "Amongst our dictionary items are such diverse elements as: %s" % arb(dictionary) 

I donโ€™t care what subject. It does not have to be random.

I can think of many ways to implement this, but they all seem wasteful. I am wondering if there are any preferred idioms in Python or (even better) if I am missing one.

 def arb(dictionary): # Creates an entire list in memory. Could take a while. return list(dictionary.values())[0] def arb(dictionary): # Creates an entire interator. An improvement. for item in dictionary.itervalues(): return item def arb(dictionary): # No iterator, but writes to the dictionary! Twice! key, value = dictionary.popitem() dictionary[key] = value return value 

I am in a situation where performance is not critical enough, that it matters (for now), so I can be blamed for premature optimization, but I'm trying to improve my Python coding style, so if I understood the option, it would be nice to accept it.

+22
python
May 15 '12 at 3:05
source share
4 answers

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

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

This works in both python 2 and python 3, but in python 2 it is more efficient to do this:

 return next(dictionary.itervalues()) 
+26
May 15 '12 at 3:09
source share

Avoiding a complete mess of values / itervalues / viewvalues , this works equally well in Python2 or Python3

 dictionary[next(iter(dictionary))] 

if you prefer generator expressions

 next(dictionary[x] for x in dictionary) 
+10
May 17 '12 at 1:55
source share

I believe that a significant answer has been given to this question, but I hope this comparison will shed some light on the trade-off between pure code and time:

 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 marginally faster than a popup and reinsert, but 10 times faster than creating a list and selecting a random object from it.

+2
Oct 18 '13 at 17:25
source share

Why not use random ?

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

This makes it clear that the result should be purely arbitrary, and not a side effect of the implementation. Until performance becomes an urgent issue, always be clear on speed.

Shame that dict_values โ€‹โ€‹does not support indexing would be nice if you could go into a value representation.

Update: since everyone is so obsessed with performance, the above function takes <120ms to return a random value from a dict of 1 million elements. Relying on clear code, this is not an amazing performance that it does.

+1
May 15 '12 at 6:59 a.m.
source share



All Articles