# Where does the 2 come from?

``````values = [[3 - x for x in range(2)] for y in range(5)]
print(values)
``````

[[3, 2], [3, 2], [3, 2], [3, 2], [3, 2]]

I understand “3 minus something” and “x for x in range(2)” equals 3 minus a variable for a loop consisting of two numbers and I understand the second “for y in range(5)” means that the previous loop will repeat 5 times… but why would anyone just assume the value of the variable to be a “1”?

Is this just a standard thing, “anytime you see an integer being added to, subtracted from, mutliplied or divided by a variable, just assume the variable is a one”?

Iterating over range(2) yields yields integers from 0 up to but excluding 2, i.e. 0 and 1.

`[3 - x for x in range(2)]`

is:

`[(3 - x) for x in range(2)]`

so that’s:

`[(3 - 0), (3 - 1)]`

or:

`[3, 2]`

3 Likes

In addition to the above, remember that statements are evaluated right-to-left, so `for x in range()` will evaluate before `3 - x`

That is not true in general.

It is not even true in general for list comprehension syntax.

``````[a for a in range(b) for b in range(3)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
``````

Should be:

``````[a for b in range(3) for a in range(b)]
# returns [0, 0, 1]
``````

Comprehension syntax evaluates left-to-right starting at the first `for` clause, and then evaluates the left-most expression. So the above example is equivalent to:

``````result = []
for b in range(3):
for a in range(b):
result.append(a)
``````

Maybe I didn’t explain myself carefully enough; the point I was making is that, with say `x = input()` the input is taken first, then attached to `x`. Likewise, with `for x in range(y)` the `y` is evaluated first, then attached to `x`.

Hell no. That would pretty much defeat the purpose of variables:

``````x = 1000
print(1 + x)
``````

That better print 1001, and not 2, or Python variables would be pointless.

We can break your code snippet into two pieces: an inner loop, and an outer loop.

The inner loop is `[3 - x for x in range(2)]`. As Matthew explains, `range(2)` evaluates to something like `[0, 1]` (the default starting value is 0, and the ending value, 2, is excluded).

So inside the inner loop, `x` takes the values 0 and then 1, and the expression `3 - x` evalues to 3 and then 2, which are collected inside a list, giving `[3, 2]`.

The the outer loop `for y in range(5)` runs the entire inner loop five times, which is why you get a list of five equal lists.

Although the value of `y` is not used, it takes the values 0, 1, 2, 3, and lastly 4, giving us five loops, each of which contributes `[3, 2]` as the result.

Until you get used to the syntax, list comprehensions are sometimes too terse to be easy to follow. We can expand your nested list comprehension into a pair of nested loops, which might be easier to understand.

``````# values = [[3 - x for x in range(2)] for y in range(5)]

# Outer loop.
values = []
for y in range(5):
# Inner loop.
result = []
for x in range(2):
result.append(3 - x)
values.append(result)
``````