Itay Braha
Itay Braha

Reputation: 3

Dictionary of lists using list comprehension

I have a string (which I treat as a list of chars) and I'm trying via dictionary comprehension to create a dictionary with the keys of every char in the string and the values as a list of the indexes in which it appeared.

For example:

pattern = "abcdabccb"

desired dictionary:

{'a' : [0,4], 'b' : [1,5,8], 'c':[2,6,7], 'd':[3]}

Best try so far:

{pattern[i]: [i] for i in range(0, len(pattern)) if pattern[i] != '_'}

returns only the last index where the char appeared.

Thanks in advance!

Upvotes: 0

Views: 1294

Answers (2)

Sumukh Barve
Sumukh Barve

Reputation: 1444

This is a fun question. You'll need a list-comprehension within a dict-comprehension:

>>> p = "abcdabccb"; # pattern
>>> {c: [i for i in range(len(p)) if p[i] == c] for c in p}
{'a': [0, 4], 'b': [1, 5, 8], 'c': [2, 6, 7], 'd': [3]}
>>> 

In plain words, here's what the comprehension says:
Compose a dictionary by iterating over every character c in the pattern p. Use each c as the key, and let the corresponding value be the list of such indices i in p, where p[i] == c.

Instead of for c in p, you may use for c in set(p) to iterate over each character just once.

As @quamrana points out, you can always use a loop. Here, a loop would be far more readable. But for honing your dict-comprehension chops, this is a pretty good practice problem.

Upvotes: 4

quamrana
quamrana

Reputation: 39354

A dictionary comprehension should be used where map or filter might have been used. The dict that you want is a summary of the input string.

You just need to fall back on a plain for loop:

from collections import defaultdict

pattern = "abcdabccb"
summary = defaultdict(list)

for idx,c in enumerate(pattern):
    summary[c].append(idx)

Output as required

Upvotes: 2

Related Questions