Getting the indexes of each element in a list of lists and making a dictionary

Viewed 440

I am trying to create a dictionary where the keys are elements of each list, and the values are their indexes in that list of lists, so that I can easily find where exactly every element is.

So if the list is [['a', 'a', 'b'], ['a', 'b', 'b'], ['c', 'c', 'c']] ,

dictionary should be like this:{'c': {(2, 0), (2, 1), (2, 2)}, 'b': {(1, 1), (1, 2), (0, 2)}, 'a': {(0, 1), (1, 0), (0, 0)}}

I can get each elements index in their respective lists with list comprehension: final_list = [list(enumerate(i)) for i in mylist] but I couldn't find a way to get their "complete" indexes that also include the index of their list.

4 Answers

you can use:

l = [['a', 'a', 'b'], ['a', 'b', 'b'], ['c', 'c', 'c']]

result = {}
for i, e in enumerate(l):
    for j, x in enumerate(e):
        result.setdefault(x, set()).add((i, j))
print(result)

output:

{'a': {(0, 0), (0, 1), (1, 0)},
 'b': {(0, 2), (1, 1), (1, 2)},
 'c': {(2, 0), (2, 1), (2, 2)}}

Here is a simple solution:

input = [['a', 'a', 'b'], ['a', 'b', 'b'], ['c', 'c', 'c']]

result = {}
for i, lst in enumerate(input):
    for j, element in enumerate(lst):
        if element in result:
            result[element].add((i, j))
        else:
            result[element] = {(i, j)}

You can do it like this:

res = {}
for i, l in enumerate(var):
    for j, letter in enumerate(l):
        res[letter] = res.get(letter, set()) | {(i, j)}

res

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

While it would be very inefficient to write a one-liner, you can use collections.defaultdict to simplify things. It's actually nicer that using dict.setdefault because it doesn't create an empty container every time you want to append a value, even when the key is already present:

result = defaultdict(list)
for i, row in enumerate(mylist):
     for j, key in enumerate(row):
         result[key].append((i, j))

A one line solution would have to make multiple passes over mylist to accumulate all the values for a given key. This would be needlessly complicated and run with O(n^2) time complexity.

Related