0

I am confused by the scope of the names argument used in following example

def disp( p1, list=[] ):
    list.append( p1 )
    return list 

list1 = disp( 10 )
list2 = disp( 123 )
list3 = disp( 'a' )

print ( list1 )
print ( list2 )
print ( list3 )

Output is

[10, 123, 'a']
[10, 123, 'a']
[10, 123, 'a']

How can we explain the scope of the variable list, which is the named argument in the function definition? Instead of a list, if it's something else, say integer, its works differently.

def disp2( p1, myVal = 0 ):
    myVal += myVal + p1 
    return myVal 

v1 = disp2(9)
v2 = disp2(7)
v3 = disp2(77)

print ( v1, v2, v3 )

Ideas? I want to understand the details behind the first example (its easy to avoid it, by changing the code ).

1

3 Answers 3

1

In Python, some types are immutable (str, int, etc.) while others are mutable (list, dict, tuple, etc).

Your code behaves like that because you are setting the default argument as mutable type (list=[]), which in returns results in the same object but with different (updated) values (content).

This article might be a good reading to understand this behaviour and how to potentially solve it.

Sign up to request clarification or add additional context in comments.

Comments

0

Python’s default arguments are evaluated once when the function is defined, not each time the function is called. This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.

https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments

Comments

0

Well the default values get assigned once only,

And your not copying the list you just added another key variable to reach it so all of them are the same list in this case

so do this

def disp( p1, list = None ):
    if list is None: # None is nothing
        list = [] 
    list.append( p1 )
    return list 

# here you don't need to copy since there different lists
# unlike then
list1 = disp( 10 )
list2 = disp( 123 )
list3 = disp( 'a' )

print ( list1 )
print ( list2 )
print ( list3 )

The output will be

[ 10 ]
[ 123 ]
[ 'a' ]

You can copy lists like this

list = Original.copy() # now those will be fundamentally different lists but same values

Or like this

list = [i for i in Original]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.