Search code examples
listdictionarypythonenumerate

pythonic way to associate list elements with their indices


I have a list of values and I want to put them in a dictionary that would map each value to it's index.

I can do it this way:

>>> t = (5,6,7)
>>> d = dict(zip(t, range(len(t))))
>>> d
{5: 0, 6: 1, 7: 2}

this is not bad, but I'm looking for something more elegant.

I've come across the following, but it does the opposite of what I need:

>>> d = dict(enumerate(t))
>>> d
{0: 5, 1: 6, 2: 7}

Please share your solutions,
Thank you

EDIT: Python 2.6.4

For lists containing 1000 elements the dict(zip) version is the fastest, the generator and the list comprehension versions are virtually identical and they are ~1.5 times slower and the functional map(reversed) is considerably slower.

$ python -mtimeit -s"t = range(int(1e3))" "d = dict(zip(t, range(len(t))))"
1000 loops, best of 3: 277 usec per loop

$ python -mtimeit -s"t = range(int(1e3))" "d = dict([(y,x) for x,y in enumerate(t)])"
1000 loops, best of 3: 426 usec per loop

$ python -mtimeit -s"t = range(int(1e3))" "d = dict((y,x) for x,y in enumerate(t))"
1000 loops, best of 3: 437 usec per loop

$ python -mtimeit -s"t = range(int(1e3))" "d = dict(map(reversed, enumerate(t)))"
100 loops, best of 3: 3.66 msec per loop

I tried running the same tests for longer and for shorter lists (1e2, 1e4, 1e5) and the time per loop scales linearly with the length of the list.

Could somebody time py 2.7+ version?


Solution

  • You can use a list comprehension (or a generator, depending on your python version) to perform a simple in-place swap for your second example.


    Using a list comprehension:

    d = dict([(y,x) for x,y in enumerate(t)])
    

    Using a generator expression (Python 2.4 and up):

    d = dict((y,x) for x,y in enumerate(t))