4

Does the evaluation of variables in print and f-string happen at different times?

I expected it to be the same output for both.

def foo(x):
    x.append([5])
    return x

y, z = [1], [3]
print('y:', y, 'z:', z)
# y: [1] z: [3]

print('y:', y, 'str(y):', str(y), 'foo(y):', foo(y))  
# y: [1, [5]] str(y): [1] foo(y): [1, [5]]

print(f'z: {z} foo(z): {foo(z)} z: {z}')
# z: [3] foo(z): [3, [5]] z: [3, [5]]

Can someone explain what is happening?

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Teebu
  • 677
  • 7
  • 18
  • Note that a format string will give you the same output as multiple args to `print`: `print('y: {} str(y): {} foo(y): {}'.format(y, str(y), foo(y)))` – wjandrea Dec 25 '19 at 02:26

1 Answers1

3

In both cases, the expressions are evaluated left-to-right. In the f-string case, each is converted (with str) immediately after evaluation, but in the case of print (which is a normal function call), all of them are evaluated (and so y is mutated) before any of them are converted to strings inside print. Explicitly writing str(y) in the call to print will produce the same results.

Davis Herring
  • 36,443
  • 4
  • 48
  • 76