55

I would like to get the value by key index from a Python dictionary. Is there a way to get it something like this?

dic = {}
value_at_index = dic.ElementAt(index)

where index is an integer

E_net4
  • 27,810
  • 13
  • 101
  • 139
Dmitry Dyachkov
  • 1,715
  • 2
  • 19
  • 46

4 Answers4

65

In Python versions before 3.7 dictionaries were inherently unordered, so what you're asking to do doesn't really make sense.

If you really, really know what you're doing, use

value_at_index = list(dic.values())[index]

Bear in mind that prior to Python 3.7 adding or removing an element can potentially change the index of every other element.

amicitas
  • 13,053
  • 5
  • 38
  • 50
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 7
    Though `OrderedDict` is available if you have the ability to change the original data construction. – Silas Ray Feb 27 '13 at 14:46
  • >> that adding or removing an element can potentially change the index of every other element. Yes I know that, this is a common sense for many iterators in many languages. – Dmitry Dyachkov Feb 27 '13 at 16:11
  • Yes, what exactly I want an index for is to get a random values within available key range, just to implement my algorithm. – Dmitry Dyachkov Feb 27 '13 at 16:19
  • I'm not sure I'd call the value at a given index "random". – MikeRand Feb 27 '13 at 21:59
  • I could not fit the full reply in here, but check out my answer below that iterates instead of creating a list. It is more accurate than this chosen answer. – sam-6174 Jul 24 '15 at 22:43
  • Doing this sort of thing is useful for inspecting a running program's dictionary when you might not necessarily know a key. i.e dict.values()[0] to see an example of a value. – Craig Brett Aug 25 '16 at 09:40
  • 32
    `dic.values()[index]` I obtain 'dict_values' object does not support indexing ..... ? (python 3.6) – B. M. Mar 19 '17 at 08:37
  • @B.M. you can do what mohammed ali shaik suggests below. – amc Jan 13 '19 at 19:50
  • 1
    `TypeError: 'dict_values' object is not subscriptable` – USERNAME GOES HERE Oct 20 '19 at 11:33
  • `list(dic.values())[index]` works – Carlos Souza Dec 24 '19 at 13:27
  • This syntax does not work in Python 3.6. Use: value_at_index = list(dic.values())[index] This converts the returned dictionary view to a bona fide list. – Andrew Dec 27 '20 at 16:48
  • I have successfully sliced my sorted dict using keys as an index... such as keywords.keys()[startid:endid] it would be a snap to make the startid value hold your random number. From this key you can get all the data you want. :) – Lenn Dolling Sep 11 '22 at 18:32
17

Let us take an example of dictionary:

numbers = {'first':0, 'second':1, 'third':3}

When I did

numbers.values()[index]

I got an error:'dict_values' object does not support indexing

When I did

numbers.itervalues()

to iterate and extract the values it is also giving an error:'dict' object has no attribute 'iteritems'

Hence I came up with new way of accessing dictionary elements by index just by converting them to tuples.

tuple(numbers.items())[key_index][value_index]

for example:

tuple(numbers.items())[0][0] gives 'first'

if u want to edit the values or sort the values the tuple object does not allow the item assignment. In this case you can use

list(list(numbers.items())[index])
9

If you really just want a random value from the available key range, use random.choice on the dictionary's values (converted to list form, if Python 3).

>>> from random import choice
>>> d = {1: 'a', 2: 'b', 3: 'c'}
>>>> choice(list(d.values()))
MikeRand
  • 4,788
  • 9
  • 41
  • 70
7

While you can do

value = d.values()[index]

It should be faster to do

value = next( v for i, v in enumerate(d.itervalues()) if i == index )

edit: I just timed it using a dict of len 100,000,000 checking for the index at the very end, and the 1st/values() version took 169 seconds whereas the 2nd/next() version took 32 seconds.

Also, note that this assumes that your index is not negative

sam-6174
  • 3,104
  • 1
  • 33
  • 34