1

If I set an empty list as the default parameter of a function I get a difference in behavior when I add elemets with the append method or when I use the "+" operator. Could someone explain why this happens?

WITH APPEND

def append_to(n, my_list = []):
    for i in range(n):
        my_list.append(str(i))
    return my_list


a = append_to(5)
print(a)
b = append_to(10)
print(b)

OUT:

['0', '1', '2', '3', '4']
['0', '1', '2', '3', '4', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

WITH "+"

def append_to(n, my_list = []):
    for i in range(n):
        my_list = my_list + [str(i)]
    return my_list


a = append_to(5)
print(a)
b = append_to(10)
print(b)

OUT:

['0', '1', '2', '3', '4']
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
simbr
  • 75
  • 1
  • 9
  • 1
    I think in the second one, ```my_list = my_list + [str(i)]``` creates a new list and over writes the ```my_list``` every time and returns it –  Aug 26 '21 at 07:44
  • @Sujay is right, your second example creates a new list. You can verify this by replacing `print(a)` with `print(id(a))` and the same with `b`. With `append` they'll have the same `id` and with `+` it will be different. – Alex Aug 26 '21 at 07:51
  • @Alex,Sujay - You are right. I checked it with the id method. But why is this so? Because obviously the pitfalls with empty mutable default arguments (e.g. my_list = []) as mentioned numerous times on stackoverflow do not apply in the second example. – simbr Aug 26 '21 at 07:59
  • Your second method will make a shallow copy of both `my_list` and `[str(i)]`. Which means a new list is created that can contain all the elements, but the values contained in the list are references to the original values. – Alex Aug 26 '21 at 08:06
  • Take a look at this [guide on shallow vs deep copy](https://realpython.com/copying-python-objects/#making-shallow-copies) and the [copy docs](https://docs.python.org/3/library/copy.html) – Alex Aug 26 '21 at 08:08
  • @Alex So in fact with the second method I never modify the original list that always remains at the value [] – simbr Aug 26 '21 at 10:14
  • Yes, I think that is correct. – Alex Aug 26 '21 at 10:17
  • @Alex `a = [] print(id(a)) out: 2499142983552 a = a + [1] print(id(a)) out: 2499143263296` – simbr Aug 26 '21 at 10:41

0 Answers0