-1

I have a list which I give to a function as argument. Inside function, I'm altering the list, but I don't return the list using return. I'm running the function and print the list afterwards.

Excpeted result: []

Actual result: [5]

How is this possible?

def foo(bar):
    for i in range(2):
        if bar == []:
            bar.append(4)
        else:
            bar[0] += 1
            
myvar = []  
foo(myvar)
print (myvar)
Martin
  • 11
  • 2

2 Answers2

1

Because empty list created first in the memory location and second time it refers same list instead of creating new one.

  • first bar =[] is empty.
  • for loop checks if bar is empty, add 4 to it.
  • Now bar = [4] so again it checks for bar == [] but now it's value is 4. So it enters into else part and add 1.
  • Now value of bar becomes 5.
  • During this process it bar refers to same memory location.

Below example will help you to understand it better way,

def foo (bar = []):
    bar.append('baz')
    return bar

foo()
['baz']


foo()

['baz', 'baz']


foo()
['baz', 'baz', 'baz']

It keep appending default value 'baz' to the existing list each time foo() was called.
This is because, the default value for a function argument is only evaluated once, at the time of function is defined. Thus the bar argument is initialized to its default(i.e. an empty list) only when foo() is first defines, but then call to foo() will continue to use the same list to which bar was originally initialized.

Rima
  • 1,447
  • 1
  • 6
  • 12
1

One thing to know about lists is that they contain references (pointers) to list objects rather than the list itself. This can be seen by running the following code:

>>> list1 = [0, 1, 2, 3]
>>> list2 = list1
>>> list1[0] = 5
>>> list2
[5, 1, 2, 3]

Here, list1 stores a reference to the list [0, 1, 2, 3], and list2 is given that same reference. When the list is modified through the reference in list1, the list referenced by list2 is also modified.

>>> def foo(bar):
        for i in range(2):
            if bar == []:
                bar.append(4)
            else:
                bar[0] += 1
            
>>> myvar = []  
>>> foo(myvar)
>>> myvar
[5]

Passing the list myvar to the function foo() as the argument bar assigns a pointer to the list [] to the parameter bar. Since myvar and bar reference the same list, when the list is modified through bar, retrieving the list through myvar reflects the same change.

Hopefully this clarifies any confusion!

Jacob Lee
  • 4,405
  • 2
  • 16
  • 37
  • "One thing to know about lists is that they contain references rather than the list itself. " that doesn't make any sense. What you are trying to say, I think, is that all variables act as references to objects. This has nothing to do with lists specifically – juanpa.arrivillaga Mar 09 '21 at 21:24