I would like to understand the way Python evaluates function calls inside print statements or, more particulary, what does the call for
next(some_iter)
return? A mutable reference to the element in the next position or just a copy of the element in the next position when some_iter
was last evaluated?
The following code:
def foo(val, arr=set()):
arr.add(val)
return arr
print(foo(1))
print(foo(2))
print(foo(1), foo(3), foo(0))
Returns the output:
{1}
{1, 2}
{0, 1, 2, 3} {0, 1, 2, 3} {0, 1, 2, 3}
Python calls the function three times, holding what seems to be a reference to arr
, then, since sets are mutable, the output is as can be seen above. foo(1)
return value was not saved, that is {1, 2}
when it is called in order of the print statement.
However
lst = [1, 2, 3, 4]
def bar(a):
a = lst
a[0] = 17
return a
x = iter(lst)
y = iter(lst)
print(next(x), bar(lst), next(y), next(x))
print(lst)
Would print
1 [17, 2, 3, 4] 17 3
[17, 2, 3, 4]
I would have expected
17 [17, 2, 3, 4] 17 3
[17, 2, 3, 4]
That is for next to hold a reference to the first element of lst, which would later be changed to 17, and for that reference to be printed as 17 eventually, but it is computed first returning 1.
Why does it not happen? In what way is the next() or iters different?