Question: How does this three deep list comprehension work? Specifically, how is `house` within scope of `bisect.bisect(heaters, house)`? My understanding of generators is that they execute in order from left to right and that piece of code is to the left of where `house` is created. Bonus: if you can rewrite this using for loops.

```
import bisect
houses, heaters = [1,2,3,90, 4],[1,4]

max(min(abs(house - heater)
   for i in [bisect.bisect(heaters, house)]
   for heater in heaters[i-(i>0):i+1])
for house in houses)

```

Answer: 
Your expression has two different generator expressions. One is inside `max` and has one `for` clause. The other is nested inside the first one, in the `min` calls, and has two `for` clauses. The indentation of your current code sort of shows the relationship with its indentation, but it could be more explicit:

```
max(
    min(
        abs(house - heater)
        for i in [bisect.bisect(heaters, house)]
        for heater in heaters[i-(i>0):i+1]
    )
    for house in houses
)

```

Here you can see the nested structure: `max(... for house in houses)` is the outer generator comprehension, while `min(abs(house-heater) for i in ... for heater in ...)` is the inner one.

The inner generator expression can refer to the iterator variable `house` from the outer generator expression (just like the function call `f(x)` in `(f(x) for x in iterable)` refers to `x`).
Rewritten using `for` loops for bonus points.

```
import bisect
houses, heaters = [1,2,3,90, 4],[1,4]

def loop1():
    for house in houses:
        def loop2():
            for i in [bisect.bisect(heaters, house)]:
                for heater in heaters[i-(i>0):i+1]:
                    yield abs(house - heater)
        yield min(loop2())

max(loop1())

```