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”?
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)