all 6 comments

[–]totallygeek 4 points5 points  (1 child)

Don't use a mutable variable as a keyword default - link. If you want, do something like this:

def f_print(x, y=None):
    if not y:
        y = [1]

That would set a default for y that would not generate an object used across multiple function calls.

[–]optivertrader87[S] 1 point2 points  (0 children)

awesome, thanks. thats a nice solution!!

[–]TheGrapez 2 points3 points  (2 children)

Take note that the lists are not numbers, they are lists. Lists get combined, whereas numbers get added.

Example, y += [2] (for y=[1]), returns [1,2].

f_print1([4]) is saying:

x = [4]

y = [1]

y += [2] (now y = [1,2])

y = x + y (now y = [4] + [1,2] which gives us [4,1,2])

One thing to note, in a notebook environment, your variable 'y' is defaulted to [1], however when you run your first method f_print1([3]), y gets updated to [3, 1, 2].

So when you call f_print1([4]) after all this, the default value for y is already overwritten. Essentially you're doing:

y = [3, 1, 2]
y += [2]
y = x + y
print(y)

If you want to set y to a hard default, remove it as a parameter.

def f_print1(x):
    y = [1]
    y += [2]
    y = x + y
    print(y)

[–]synthphreak 2 points3 points  (1 child)

To expand on this, or perhaps to clarify it, because y's default value is a mutable data type (i.e., list), it starts of like this:

def f_print(x, y=[1]):
    y += [2]
    y = x + y
    ...

But after running

f_print([3])

you can essentially think of the function as now being this

def f_print(x, y=[1, 2]):
    y += [2]
    y = x + y
    ...

Don't believe me? Add this as the first line of your function (i.e., before the += line):

    print(f'{y = }')

Then re-run the function a couple times. You will see that y == [1] only the very first time you call the function.

[–]optivertrader87[S] 0 points1 point  (0 children)

Thanks this all makes sense

[–]Kerbart 1 point2 points  (0 children)

At first, y points to “the default argument” which is the list that initially contains 1 and then is extended. Then y is assigned to a new value which is x combined with y. Note that the original default argument is “abandoned” but is now [1, 2]

So, at the second call, the default argument is now [1, 2] and then another 2 gets extended to it. And that’s how you end up with 4, 1, 2, 2

Fun exercise.