Reputation: 189626
I understand that the Python interpreter is a REPL... but in a loop, the "value" of the loop must be single-valued... correct? And yet I see this (tested in both Python 2.7.18 and 3.8.5 with range
instead of xrange
):
>>> for _ in xrange(5):
... 3
...
3
3
3
3
3
Where is this behavior documented in Python?
It seems to get suppressed when in a called function:
>>> def foo(x):
... 1
... x
... return x+1
...
>>> foo(5)
6
>>> def bar(n):
... for x in xrange(5):
... 1
... x
... return n+1
...
>>> bar(5)
6
>>> for x in xrange(5):
... 1
... x
...
1
0
1
1
1
2
1
3
1
4
Note to downvoters: This is not an obvious behavior! Contrast with Javascript:
> for (var i = 0; i < 5; ++i) {
i
}
4
Upvotes: 0
Views: 197
Reputation: 1797
Its because you are using Python interactive interpreter (REPL). REPL always calls the repr method of the object. In your case it is 3.
If you try creating a .py file of this code and run it. Nothing will be printed and the program will just run and close.
Upvotes: 1
Reputation: 189626
OK I think I found something definitive in the Python docs under expression statements:
6.1. Expression statements
Expression statements are used (mostly interactively) to compute and write a value, or (usually) to call a procedure (a function that returns no meaningful result; in Python, procedures return the value None). Other uses of expression statements are allowed and occasionally useful. The syntax for an expression statement is:
expression_stmt ::= expression_list
An expression statement evaluates the expression list (which may be a single expression).
In interactive mode, if the value is not
None
, it is converted to a string using the built-inrepr()
function and the resulting string is written to standard output (see section The print statement) on a line by itself. (Expression statements yieldingNone
are not written, so that procedure calls do not cause any output.)
Upvotes: 0
Reputation: 59096
Evidently the REPL shows the result of every expression executed as a statement, not just the outer statement (the for-loop). The for-loop itself does not have any value at all: it is just a statement, not an expression.
Incidentally, you can see the same thing in other constructions, such as an if-statement:
if True:
1 + 2
"Hello"
shows
3
'Hello'
in the REPL.
Presumably the reason it does not do the same thing for expressions inside functions is that it would produce so much extraneous information that it would only cause confusion.
Upvotes: 1
Reputation: 1083
It's not the "value" of the loop that's resulting in 3 being displayed. It's the result of the interpreter evaluating 3.__repr__()
on each iteration of the loop.
For instance if you instead evaluated i
you would get the following.
for i in range(5):
i
# 0
# 1
# 2
# 3
# 4
If you want a for loop that doesn't display anything you'll want to make sure that all statements in the loop don't print anything when evaluated in the interpreter. An example of such a statement would be.
for i in range(5):
_ = None
The reason that for loops don't have a "final value" (unlike your javascript example) is because in Python for loops are statements, and statements in Python don't have a value.
Upvotes: 2
Reputation: 77837
You're confusing levels of abstraction. Every statement has its value. In the case of your loop, you interpret the line 3
five times, and thus have five non-empty results returned. The interactive interpreter prints that value each time.
To see it a little more clearly, change the expression:
for i in range(5):
i
Upvotes: 1
Reputation: 1382
The interpreter will print out any variables you just type out ..
It's just a convenience function.
If you type in "3" in the interpreter, it will also print out "3".
Upvotes: 1