Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add index into a dict

For example, given:

['A', 'B', 'A', 'B']    

I want to have:

{'A': [0, 2], 'B': [1, 3]}

I tried a loop that goes like; add the index of where the character is found, then replace it with '' so the next time the loop goes through, it passes on to the next character.

However, that loops doesn't work for other reasons, and I'm stuck with no idea how to proceed.

like image 805
Long Vuong Avatar asked Apr 04 '16 05:04

Long Vuong


People also ask

Is indexing possible in dictionary?

An index or key is not part a list content. But in dictionary we need to have a key or index attached to every element which is referred as value.

Can we use index in dictionary Python?

Python dictionary index of key By using list(*args) with a dictionary it will return a collection of the keys. We can easily use the index to access the required key from the method and convert it to a list. In this example to use the list[index] function and it will return the key at index in the list.

How do you value a dictionary by index?

Access Dictionary Elements Using Indexvar element = capitals. ElementAt(2); The ElementAt method provides us array-like access capability to key-value pairs of Dictionary<string, string> . As with C# arrays, the index of the first element is 0.

Can you append to a dict?

HTML code can be appended to a div using the insertAdjacentHTML() method. However, you need to select an element inside the div to add the code. This method takes two parameters: The position (in the document) where you want to insert the code ('afterbegin', 'beforebegin', 'afterend', 'beforeend')


3 Answers

Use enumerate and setdefault:

example = ['a', 'b', 'a', 'b']
mydict = {}
for idx, item in enumerate(example):
     indexes = mydict.setdefault(item, [])
     indexes.append(idx)
like image 121
willnx Avatar answered Oct 22 '22 19:10

willnx


A simple dictionary comprehension should do the trick:

{key: [index for index, x in enumerate(my_list) if x == key] for key in my_list}

A simple trial:

>>>> my_list = ['A','B','A','B']
>>>> {key: [index for index, x in enumerate(my_list) if x == key] for key in my_list}
>>>> {'A': [0, 2], 'B': [1, 3]}

How It Works

List comprehensions are often used in Python as syntactic sugar for a for loop. Instead of writing

my_list = []
for item in range(10):
    my_list.append(item)

list comprehensions essentially let you condense this series of statements into a single line:

my_list = [item for item in range(10)]

Whenever you see a list comprehension, you should remember that it's just a condensed version of the original three line statement. They are effectively identical - the only benefit offered here is conciseness.

A similar, related species is the dictionary comprehension. It is similar to the list comprehension, except that it allows you to specify both the keys and values at the same time.

An example of a dictionary comprehension:

{k: None for k in ["Hello", "Adele"]}
>>>> {"Hello": None, "Adele": None}

In the answer I provide, I have simply used a dictionary comprehension that

  • Pulls out keys from my_list
  • Assigns a list of indices for each key from my_list as the corresponding value

Syntactically, it expands out into a fairly complicated program that reads like this:

my_dict = {}
for key in my_list:
    indices = []
    for index,value in enumerate(my_list):
         if value == key:
              indices.append(index)
    my_dict[key] = indices

Here, enumerate is a standard library function that returns a list of tuples. The first element of each tuple refers to an index of the list, and the second element refers to the value at that index in the list.

Observe:

 enumerate(['a','b','a','b'])
 >>>> [(0,'a'),(1,'b'),(2,'b'),(3,'b')]

That is the power of enumerate.

Efficiency

As always, premature optimisation is the root of all evil. It is indeed true that this implementation is inefficient: it duplicates work, and runs in quadratic time. The important thing, however, is to ask if it is okay for the specific task you have. For relatively small lists, this is sufficient.

You can look at certain optimisations. @wilinx's way works well. @Rob in the comments suggests iterating over set(my_list), which prevents duplicated work.

like image 39
Akshat Mahajan Avatar answered Oct 22 '22 20:10

Akshat Mahajan


Why not use defaultdict from itertools instead:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> 
>>> for i,x in enumerate(l):
        d[x].append(i)


>>> d
defaultdict(<class 'list'>, {'A': [0, 2], 'B': [1, 3]})
like image 39
Iron Fist Avatar answered Oct 22 '22 19:10

Iron Fist