on running
[print(n) for n in range(5)]
it gives
0
1
2
3
4
[None, None, None, None, None]
on running
[print(n) for n in range(5)]
it gives
0
1
2
3
4
[None, None, None, None, None]
The list comprehension effectively does this:
L = []
for n in range(5):
r = print(n)
L.append(r)
print(L)
print(...) has the side-effect of displaying the arguments to screen, but has a return value of None. This is why a list of Nones is created. However, when you run this in the shell, you're asking to see the list-comp'd list... which is five Nones
print() doesn't return anything. So, when you call
[print(n) for n in range(5)], it's printing n 5 times as it creates an array of 5 Nones.
print(n) returns None so the resulting list from the list comprehension will be [None]*5
print doesn't return its argument; it writes it to the file handle used for standard output and returns None. The expected list is produced by [n for n in range(5)].
Interactive interpreters confuse the issue a bit because they always print the value of an expression to standard output after evaluating it. In your example, standard output gets 0 through 4 written by the evaluation of the calls to print, then the interpreter itself prints the string representation of the resulting list to standard output as well. If you put the same code in a file and run it outside an interactive interpreter, you'll see only the first 5 lines, but not the resulting list.