Reputation: 123
I am doing some graph theory and I use the NetworkX library.
In some algorithms, one needs to get an arbitrary item from a dictionary to start it (for instance, one of the neighbors of a given node, and the neighborhoods are a dict in NetworkX).
By arbitrary element I mean any element, I don't care which one (not a given element, not a random element, etc.)
Currently I do the following:
D = {i:i**2 for i in range(N)} # an example of a dictionary where N is a positive integer
any_item_of_D = list(D)[0] # getting a item of D
But it appears that the time complexity of any_item_of_D = list(D)[0]
is linearly growing as N tends to infinity (a O(N) complexity).
Is it possible to get an arbitrary item from a dictionary with a O(1) complexity in Python?
Upvotes: 1
Views: 348
Reputation: 362557
Pop item returns an arbitrary item in O(1), which you can then put back into the dict (also O(1)).
key, val = D.popitem()
D[key] = val
Since Python 3.7 LIFO order is guaranteed for dict.popitem
, so you don't have to worry about it messing up ordering either.
This is significantly faster than creating an item iterator just to get the first item:
>>> timeit k,v = D.popitem(); D[k] = v
107 ns ± 0.0716 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
>>> timeit next(iter(D.items()))
164 ns ± 0.0687 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Note that next(iter(ordered_dict))
is O(1) but next(iter(std_dict))
can be O(n) in worst-case.
Upvotes: 2
Reputation: 6776
I have "always" done next(iter(D.items()))
, but to be honest, I have never checked whether it is the most efficient way...
Upvotes: 0