From this website, there is a way to form a list in Python from loop in one line
squares = [i**2 for i in range(10)]
My question is, typically, after a loop, there is a colon, e.g.,
squares = []
for i in range(10):squares.append(i**2)
why in the one-line approach, there is no colon? Is there any underlying reason than convention?
Note (in addition to what have been said in comments: it is syntax of the language. There is usually no obvious reason to "why" a syntax rule exist, other that "because". Because the author decided so), that this is not the same for
. Those are two different meanings of the keyword for
. The reason why the same keyword could be used for both usage is because context makes it never ambiguous. And one of the element of context that makes it unambiguous is precisely the presence of absence of colon.
The first for
is a control structure, deciding in which order are executed imperative instruction
for i in iterable:doSomething
instruct the interpreter to repeat the imperative instruction doSmething manytimes, one, for each values in the iterable, and with a local environment containing i
being those values one after each other. No need to say more. You certainly already know what a for
loop is. I describe it only for contrast to the next usage
[expr(i) for i in iterable]
This is NOT a for loop. It has nothing, or very few, to do with previous instruction. To start with, it is not even an instruction!
This is an expression. [expr(i) for i in iterable]
does nothing (unless you implemented some "side-effect" to expr(i)
or even to the iteration of the iterable, so let say, it, a priori does nothing). It does nothing but has a value.
So it is the same difference as between the instruction print(12)
which has no value, but does something, and the expression 12
which does nothing, but has a value.
So there is no reason to find the same syntax, and in particular the colon, separating the for
part from the list of instructions that are supposed to be repeated, since there is no list of instructions.
You can find the same difference (and answer would probably have been more easy to spot with this second example) with the if
keyword.
if condition:doSomething()
else:doSomethingElse()
is an instruction.
12 if condition else 15
is an expression.
The first one has no value. You can't
x=if condition:doSomething
else:doSomethingElse
But has effect.
The second one has a priori no effect, but has a value. You can
x=12 if condition else 15
So the first one is the same as print(something)
when the second one is the same as 12
. The first does something, the second's value is something.
So, here again, it is not at all the same if
. The context makes it obvious which one it is (for example because the first one use a colon, the second doesn't). But those are two very different part of the language (even tho, of course, like for for, we easily see why, from a human point of view, it makes sense to call both if
, or all both for
for your initial example)
There are some languages, for example C, where those two construct have not at all the same name. Proving that, indeed, these are not the same thing.
In C, the first one would be
if(condition){doSomething();
}else{doSomethingElse();
}
While the second one would be
condition?12:15
for example
x=condition?12:15
My point, by bringing C, is to show that those two if
have nothing to do. In C, one is if
the other is the ternary operator ...?...:...
.
In python, the ternary operator and the if control structure happen to use the same keyword, but with different syntax, that's all.
The reason why I brought up if
example, besides being a second example worth noting of language syntax that has nothing to do which each other, while sharing a same keyword, is because with for
it would have been harder for me to show you examples of other languages where the 2 things use different keywords, for the simple reason that python's [... for ...]
is quite unique, at least among most classical languages. There is no equivalent of that in C, C++, C#, Java, Javascript, etc. But yet, this is not a for loop.
So, short answer: [... for ...]
doesn't have a colon like in for loops, because it is not a for loop.