0

I have the following dictionary:

d = {}
d[1] = 'a'
d[2] = 'b'
d[3] = 'c'
d[4] = 'd'

I'd like to perform a reverse dictionary lookup for each character in a string:

input_string = "bad"

I get different results when I do this in a list comprehension as opposed to a nested for loop, and I don't understand why. As I understand, the list comprehension and the nested for loop should yield identical results. The list comprehension yields a list whose results are not in the order I would expect. My desired result here is that which is provided by the nested for loop, however I prefer to use the list comprehension to accomplish that. Perhaps this has something to do with python dictionary order of which I am unaware?

result1 = [key for key, value in d.items() for i in input_string if i == value]
print(result1)


> [1, 2, 4]


result2 = list()
for i in input_string:
    for key, value in d.items():
        if i == value:
            result2.append(key)

print(result2)

> [2, 1, 4]
capt-calculator
  • 722
  • 5
  • 12
  • 1
    The structure of multiple loops in a list comprehension is: `[i for inner_loop in outer_loop for i in inner_loop]`. [Double Iteration in List Comprehension](https://stackoverflow.com/questions/1198777/double-iteration-in-list-comprehension) contains some more examples. – 0x5453 May 09 '22 at 20:49
  • Well, because your list comprehension is not equivalent to your for loop. In the for-loop, the `for i in input_string` comes first, nested inside of that is `for key, value in d.items()`, on the other hand, in your list comprehension, `for key, value in d.items()` comes first, and `for i in input_string` is nested. – juanpa.arrivillaga May 09 '22 at 22:48
  • Note, you really should make the reverse mapping up front anyway, `dr = {v: k for k, v in d.items()}` then just `[dr[c] for c in "bad"]` – juanpa.arrivillaga May 09 '22 at 22:50

1 Answers1

1

In order to mimic the traditional loop, the outer loop should be over input_string and the inner loop should be over d in the list comprehension:

out = [k for i in input_string for k,v in d.items() if i==v]

Output:

[2, 1, 4]
  • Yea, I meant input_string. Edited. As for the issue at hand, thank you. I see that I just had the loops in the wrong order. – capt-calculator May 09 '22 at 20:55
  • @capt-calculator I meant, as it's written, the outer loop is over `d` and the inner loop is over `input_string` in your code, which is giving you the wrong output. If you change the order (which is the correct order to search as it's used in the traditional loop), you get the correct output. –  May 09 '22 at 20:58