1

Can someone explain how to do nested dict comprehensions?

>> l = [set([1, 2, 3]), set([4, 5, 6])]
>> j = dict((a, i) for a in s for i, s in enumerate(l))
>> NameError: name 's' is not defined

I would have liked:

>> j
>> {1:0, 2:0, 3:0, 4: 1, 5: 1, 6: 1}

I just asked a previous question about a simpler dict comprehension where the parentheses in the generator function were reduced. How come the s in the leftmost comprehension is not recognized?

Community
  • 1
  • 1
atp
  • 30,132
  • 47
  • 125
  • 187

1 Answers1

5

Just reverse the order of the two loops:

j = dict((a, i) for i, s in enumerate(l) for a in s)
satoru
  • 31,822
  • 31
  • 91
  • 141
  • This works. However I read in the manual (http://docs.python.org/tutorial/datastructures.html) that "Special care has to be taken for the nested list comprehension: To avoid apprehension when nesting list comprehensions, read from right to left." Why doesn't this apply? – atp Jan 09 '11 at 11:50
  • @Jasie Because what we are doing here is not nested list comprehension. Nested list comprehension is like `[ [i*j for j in range(3)] for i in range(3)]`. The tool we use here is not list comprehension at all, it is a generator expression. – satoru Jan 09 '11 at 12:03
  • 3
    From PEP 202 (http://www.python.org/dev/peps/pep-0202/), according to the BDFL: `The form [... for x... for y...] nests, with the last index varying fastest, just like nested for loops.` The point isn't which type of expression we are using, it is the nested-for-loop syntax of the list comprehension. – Katriel Jan 09 '11 at 12:13