-1

I have a list of elements, lets say:

y = [1, 3, 1, 5, 1]

And I would like to create a dictionary where:

  • Keys: are the elements in y
  • Values: is a list of the elements that appear before the Key in y

I attempted the following comprehension.

a={elem:y[i] for i, elem in enumerate(y[1:])}

However, since the value field in the dictionary is not a list, it only keeps the previous element in the last occurrence of the key.

In other words, for this example I get the following:

{3: 1, 1: 5, 5: 3}

Is there a way to do so using comprehensions ?

Note: I forgot to add the desired result.

{3: [1], 1: [3,5], 5: [1]}

donatorolo
  • 81
  • 6

3 Answers3

2

Your keys are duplicated, so you cannot create a dictionary with them (you'll lose the first elements).

So comprehensions are difficult to use (and inefficient, as stated by other comprehension answers here) because of the accumulation effect that you need.

I suggest using collections.defaultdict(list) instead and a good old loop:

import collections

y = [1, 3, 1, 5, 1]

d = collections.defaultdict(list)

for i,x in enumerate(y[1:]):
    d[x].append(y[i])  # i is the index of the previous element in y

print(d)

result:

defaultdict(<class 'list'>, {1: [3, 5], 3: [1], 5: [1]})
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
1

Just for the fun of it. Here's a comprehension.

a = {y[i]: [y[x-1] for x in range(len(y)) if y[x]==y[i]] for i in range(1, len(y))}

>> {3: [1], 1: [3,5], 5: [1]}

Just note that it's too long and inefficient to be allowed in any practical program.

Using the defaultdict as Jean-François Fabre suggested in his answer below should be the proper way.

thithien
  • 235
  • 1
  • 12
1

Use enumerate and set operations.

{value: set(y[:i]) - {value} for i, value in enumerate(y)}
Out: {1: {3, 5}, 3: {1}, 5: {1, 3}}

It's a bit ugly and inefficient because in your example it works out a new answer each time it encounters 1, but it works out right because the final time it does this is the final time it encounters 1.

Denziloe
  • 7,473
  • 3
  • 24
  • 34