On 29/01/2013 10:44, Nick Coghlan wrote:
Terry is correct: comprehensions are deliberately designed to have the exact same looping semantics as the equivalent statements flattened out into a single line, with the innermost expression lifted out of the loop body and placed in front. This then works to arbitrarily deep nesting levels. The surrounding syntax (parentheses, brackets, braces, and whether or not there is a colon present in the main expression) then governs what kind of result you get (generator-iterator, list, set, dict).
For example in:
(x, y, z for x in a if x for y in b if y for z in c if z) [x, y, z for x in a if x for y in b if y for z in c if z] {x, y, z for x in a if x for y in b if y for z in c if z} {x: y, z for x in a if x for y in b if y for z in c if z}
The looping semantics of these expressions are all completely defined by the equivalent statements:
for x in a: if x: for y in b: if y: for z in c: if z:
(modulo a few name lookup quirks if you're playing with class scopes)
Thanks for spelling this out so clearly. It helps me remember which order to place nested "for"s inside a list comprehension! :-)