Nested loops are a common pattern in programmation in most programming languages. In Python, nested loops that have a long body must indent at each loop, that's wastes screen space and hides the fact the code is in an unique loop.
In addition, break statements in the outermost loop will continue with the next parent loop. If the intent is to break the outermost loop, the programmer needs to include these nested loops in an outer try ... except structure that adds one more indentation level, or add a loop logic control.
This recipe can be used in most cases you need nested loops that are merged in one. The "black magic": merge the looping logic in a generator expression.
Before:
must_break_all = False
for obj1 in iterable1:
if must_break_all:
break
for obj2 in iterable2:
if must_break_all:
break
for obj3 in iterable3:
lots_of_data_processing()
if we_must_stop():
must_break_all = True
break
other_data_processing()
# End all iterations
doing_something_else()
Ugly, isn't it?
In place of this I prefer use a generator expression that merges the looping logic, like this:
merged_looping = ((obj1, obj2, obj3)
for obj1 in iterable1
for obj2 in iterable2
for obj3 in iterable3)
for obj1, obj2, obj3 in merged_looping:
lots_of_data_processing()
if we_must_stop():
break
other_data_processing()
# End all iterations
doing_something_else()
And yes, you can put any number of consistent for expressions in one generator expression.
Warning
Exhausted generator
You can't re-use merged_looping as is after the last line of this example because it is potentially exhausted.
Comments !