157

I have a Dictionary below:

colors = {
    "blue" : "5",
    "red" : "6",
    "yellow" : "8",
}

How do I index the first entry in the dictionary?

colors[0] will return a KeyError for obvious reasons.

martineau
  • 119,623
  • 25
  • 170
  • 301
Harpal
  • 12,057
  • 18
  • 61
  • 74
  • 6
    What does "first" mean? Dictionaries have no ordering. – S.Lott Dec 01 '10 at 17:54
  • 9
    Dictionaries is now insertion ordered since Python 3.7 Check this out: https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6 – Nikita Alkhovik Aug 07 '18 at 21:17
  • Related: [Accessing dictionary items by position in Python 3.6+ efficiently](https://stackoverflow.com/questions/52507860/accessing-dictionary-items-by-position-in-python-3-6-efficiently) – jpp Oct 20 '18 at 13:52

11 Answers11

231

If anybody is still looking at this question, the currently accepted answer is now outdated:

Since Python 3.7*, dictionaries are order-preserving, that is they now behave like collections.OrderedDicts. Unfortunately, there is still no dedicated method to index into keys() / values() of the dictionary, so getting the first key / value in the dictionary can be done as

first_key = list(colors)[0]
first_val = list(colors.values())[0]

or alternatively (this avoids instantiating the keys view into a list):

def get_first_key(dictionary):
    for key in dictionary:
        return key
    raise IndexError

first_key = get_first_key(colors)
first_val = colors[first_key]

If you need an n-th key, then similarly

def get_nth_key(dictionary, n=0):
    if n < 0:
        n += len(dictionary)
    for i, key in enumerate(dictionary.keys()):
        if i == n:
            return key
    raise IndexError("dictionary index out of range") 

* CPython 3.6 already included insertion-ordered dicts, but this was only an implementation detail. The language specification includes insertion-ordered dicts from 3.7 onwards.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Pasha
  • 6,298
  • 2
  • 22
  • 34
136

Dictionaries are unordered in Python versions up to and including Python 3.6. If you do not care about the order of the entries and want to access the keys or values by index anyway, you can create a list of keys for a dictionary d using keys = list(d), and then access keys in the list by index keys[i], and the associated values with d[keys[i]].

If you do care about the order of the entries, starting with Python 2.7 you can use collections.OrderedDict. Or use a list of pairs

l = [("blue", "5"), ("red", "6"), ("yellow", "8")]

if you don't need access by key. (Why are your numbers strings by the way?)

In Python 3.7, normal dictionaries are ordered, so you don't need to use OrderedDict anymore (but you still can – it's basically the same type). The CPython implementation of Python 3.6 already included that change, but since it's not part of the language specification, you can't rely on it in Python 3.6.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 3
    In Python 2, use `d.iterkeys().next()` instead of `d.keys()[0]` to inspect one of the keys without removing it. If the dictionary is huge, it will make a big difference in terms of performance. The same goes for values and items. In Python 2.7 you can also use [dict view objects](http://docs.python.org/2/library/stdtypes.html#dictionary-view-objects) – simleo Feb 28 '14 at 10:42
  • 51
    In Python 3, these calls return a view, rather than an actual list so you should wrap them in a call to list() otherwise you will see: "TypeError: 'dict_values' object does not support indexing". See this S.O. question: http://stackoverflow.com/questions/17431638/get-typeerror-dict-values-object-does-not-support-indexing-when-using-python – stifin Mar 05 '15 at 16:43
  • 4
    Just a nit of a correction: you can't index items(), at least not in Python 3. – John Strong Nov 03 '17 at 15:35
  • 3
    This answer is outdated for python 3.6+, please see answer by @Pasha below. – hans Aug 03 '18 at 09:16
  • 2
    @hans This answer is outdated for Python 3.7, but not for Python 3.6, since the order-preserving nature of dictionaries is an implementation detail of the CPython implementation of that Python version, not an official part of the language. I'll update this answer accordingly. – Sven Marnach Aug 03 '18 at 10:30
  • @hans I just noticed that you made the same comment on the other answer. :) – Sven Marnach Aug 03 '18 at 10:31
3

Addressing an element of dictionary is like sitting on donkey and enjoy the ride.

As a rule of Python, a DICTIONARY is orderless

If there is

dic = {1: "a", 2: "aa", 3: "aaa"}

Now suppose if I go like dic[10] = "b", then it will not add like this always

dic = {1:"a",2:"aa",3:"aaa",10:"b"}

It may be like

dic = {1: "a", 2: "aa", 3: "aaa", 10: "b"}

Or

dic = {1: "a", 2: "aa", 10: "b", 3: "aaa"}

Or

dic = {1: "a", 10: "b", 2: "aa", 3: "aaa"}

Or any such combination.

So a rule of thumb is that a DICTIONARY is orderless!

Neel Sandell
  • 429
  • 5
  • 12
Raj Damani
  • 782
  • 1
  • 6
  • 19
  • this is very straitforward... I like it! – Alex Liu 33214 Jun 27 '20 at 21:32
  • 6
    In python >3.6 dictionaries preserve its order, so this answer is maybe simple but also misleading. In python >3.6 code represented by @RajDamani always leads to `{1:"a",2:"aa",3:"aaa",10:"b"}` – Viljami Mar 11 '21 at 12:31
3

If you need an ordered dictionary, you can use odict.

Utku Zihnioglu
  • 4,714
  • 3
  • 38
  • 50
3

oh, that's a tough one. What you have here, basically, is two values for each item. Then you are trying to call them with a number as the key. Unfortunately, one of your values is already set as the key!

Try this:

colors = {1: ["blue", "5"], 2: ["red", "6"], 3: ["yellow", "8"]}

Now you can call the keys by number as if they are indexed like a list. You can also reference the color and number by their position within the list.

For example,

colors[1][0]
// returns 'blue'

colors[3][1]
// returns '8'

Of course, you will have to come up with another way of keeping track of what location each color is in. Maybe you can have another dictionary that stores each color's key as it's value.

colors_key = {'blue': 1, 'red': 6, 'yllow': 8}

Then, you will be able to also look up the colors key if you need to.

colors[colors_key['blue']][0] will return 'blue'

Something like that.

And then, while you're at it, you can make a dict with the number values as keys so that you can always use them to look up your colors, you know, if you need.

values = {5: [1, 'blue'], 6: [2, 'red'], 8: [3, 'yellow']}

Then, (colors[colors_key[values[5][1]]][0]) will return 'blue'.

Or you could use a list of lists.

Good luck!

2

actually I found a novel solution that really helped me out, If you are especially concerned with the index of a certain value in a list or data set, you can just set the value of dictionary to that Index!:

Just watch:

list = ['a', 'b', 'c']
dictionary = {}
counter = 0
for i in list:
   dictionary[i] = counter
   counter += 1

print(dictionary) # dictionary = {'a':0, 'b':1, 'c':2}

Now through the power of hashmaps you can pull the index your entries in constant time (aka a whole lot faster)

joechoj
  • 1,339
  • 10
  • 12
user3368835
  • 357
  • 2
  • 7
  • 15
  • might want to use a different variable name than `list` as you are shadowing the built-in constructor for lists `list()` – jorf.brunning Apr 14 '21 at 17:06
2

Consider why you are indexing

First, I would say to make sure you really need to index into the dict. A dict was originally intended not to even have an order, so perhaps there is alternate way to resolve the need to index that uses the strengths of the existing base Python data types.

For example, if you have a list of colors that are needed in a certain order, just store the list of colors, then index into those, and feed them into the dict to get the values.

color_order = [ 'blue', 'yellow', 'yellow', 'blue' ]
value_0 = colors[color_order[0]]

On the other hand, if you need some default color value as index 0, consider using a separate value to store the default, or add an additional entry that sets the default value that you can just key into instead of having to index:

default_color = 'blue'
default_value = colors[default_color]

colors = { 'default': '5', 'blue': '5', 'red': '6', 'yellow': '8' }
default_value = colors['default']

Find the index with a function

You can find a dict index by counting into the dict.keys() with a loop. If you use the enumerate() function, it will generate the index values automatically.

This is the most straight-forward, but costs a little more CPU every time you look up the index. This assumes an ordered dict (Python 3.7+ guarantees this).

To find the key at a given index:

def key_at_index(mydict, index_to_find):
  for index, key in enumerate(mydict.keys()):
    if index == index_to_find:
      return key
  return None  # the index doesn't exist

To find the index of an key:

def index_of_key(mydict, key_to_find):
  for index, key in enumerate(mydict.keys()):
    if key == key_to_find:
      return index
  return None  # the key doesn't exist

Create a list of keys

If you need a solution that will be accessed a lot, you can create a duplicate list of the keys that mirrors the keys in your current dictionary, then index into the list if you know the index, or use the list.index(item) method of the list to find the index. A list is preferable to creating a dict with the indexes, because a list inherently already has indexes, and built-in functions are typically much faster and more likely to correctly handle edge and corner cases.

There is extra overhead with this method, but it could be worth it if you are doing a lot of data analysis and need to access the indexes regularly.

# Note: you don't actually need the `.keys()`, but it's easier to understand
colors_i = list(colors.keys())
index_blue = colors.index('blue')
index0 = colors_i[0]
value0 = colors[index0]

print(f'colors: {colors}\ncolor_i: {colors_i}')
print(f'index_blue = {index_blue}, index0 = "{index0}", value0 = "{value0}"')
# colors: {'blue': '5', 'red': '6', 'yellow': '8'}
# color_i: ['blue', 'red', 'yellow']
# index_blue = 0, index0 = "blue", value0 = "5"

Note: This is static, and will not be updated if your source dictionary get's updated. You will need to add new items to both the list and the dict to keep them in sync

Function to update the dict and list

The below is a function that will update your dict and index list at the same time. If an item already exists, it will update the value and not add it to the list (otherwise there will be a duplicate entry in the list, while the dict will only update the existing entry).

This approach could be extended into a class if doing large amounts of processing, especially if other extended functions are required on top of this.

def index_add_item(mydict, index_list, key, value):
  # Note: The dict and list are passed by reference, so we can just update them
  try: # in case key doesn't exist
    existing_value = colors[key]
  except KeyError: # key does not exist, update dict and list
    mydict.update({key: value})
    index_list.append(key)
  else: # key already exists, just update value
    mydict[key] = value

index_add_item(colors, colors_i, 'purple', '99')
print(f'colors: {colors}\ncolors_i: {colors_i}')
# colors: {'blue': '5', 'red': '6', 'yellow': '8', 'purple': '99'}
# colors_i: ['blue', 'red', 'yellow', 'purple']

index_add_item(colors, colors_i, 'blue', '1')
print(f'colors: {colors}\ncolors_i: {colors_i}')
# colors: {'blue': '1', 'red': '6', 'yellow': '8', 'purple': '99'}
# colors_i: ['blue', 'red', 'yellow', 'purple']
LightCC
  • 9,804
  • 5
  • 52
  • 92
1

You can't, since dict is unordered. you can use .popitem() to get an arbitrary item, but that will remove it from the dict.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • `next(iter(d.items()))` (`.iteritems()` in Python 2) gives you an arbitrary item as well (the same in my tests, which makes sense since popitem can be implemented using this) but won't remove the item. –  Dec 01 '10 at 16:49
0

I moved further with LightCC answer:

def key_value(mydict, find_code, find_key, return_value):
  for key in mydict:
    if key[find_code] == find_key:
      return key[return_value]
  return None

and I am not sure if this def could be optimized further (as nearly as oneliner).

pbies
  • 666
  • 11
  • 28
0

Given a dict mydict in Python 3.7 and later, after dict became ordered by order of insertion, one can do:

  • next(iter(mydict.items())) to retrieve the first key, value pair that was inserted.
  • next(iter(mydict.keys())) to retrieve the first key that was inserted.
  • next(iter(mydict.value())) to retrieve the first value that was inserted.

This approach does not require iterating through all the elements of the dictionary.

Jorge Moraleda
  • 362
  • 3
  • 8
0

Simple code that works.

# Example dictionary
d = {
    'a': 5,
    'b': 6,
    'c': 7,
    'd': 8,
    'e': 9,
}
# Index you want
index = 3 
# Use the fact that d.keys() is ordered the same as d.values()
value = d[list(d.keys())[index]] 
print(value)

Will print

8

Keys and values are ordered the same according to this question

Salonik Resch
  • 21
  • 2
  • 4