Zining Zhu
Zining Zhu

Reputation: 323

Python modifying list within function

I am trying to let a function modify a list by passing the list's reference to it. The program below shows when I pass a list into the function, only a local variable is generated. Is there any ways to select some members from that list within a function? Thank you.

def func(list1):
    list1 = list1[2:]    
    print(list1)   # prints [2, 3]

list1 = [0, 1, 2, 3]
func(list1)
print(list1)       # prints [0, 1, 2, 3]

Edit1: I also tried to use the following function. It also doesn't work. Maybe it's because in func2 list1 becomes a local variable referencing to list2.

def func2(list1):
    list2 = list1[2:]    
    list1 = list2
    print(list1)   # prints [2, 3]

list1 = [0, 1, 2, 3]
func(list1)
print(list1)       # prints [0, 1, 2, 3]

Upvotes: 6

Views: 12700

Answers (6)

Javi
Javi

Reputation: 135

If you assign a value to a variable within a function, then that variable is considered local and is destroyed at the end of the block.

In your code you are assigning to list1 a value , list1[2:] from now list1 is a local variable and therefore will be destroyed when the block ends.

The list1 variable does not change out of the function.

Upvotes: 2

cizixs
cizixs

Reputation: 13981

please goto http://www.pythontutor.com/visualize.html to visualize your code. It'll give you a more accurate explanation.

Here is a short explanation and two possible solutions for you question:

list1 = list1[2:]

This line creates a new list and assign it to local variable list1 in func namespace, while keeps the global one still. enter image description here

If you want to change the original list:

  1. Please use change in place methods(remove, pop etc) for list which can be found here.

  2. Or you can return a new list like this:

    def func(list1):
        list1 = list1[2:]    
        print(list1)   # prints [2, 3]
        return list1
    
    list1 = [0, 1, 2, 3]
    list1 = func(list1)
    print(list1)       # prints [2, 3]
    

Hope it helps.

Upvotes: 3

Francisco Meza
Francisco Meza

Reputation: 883

option 1: don't do it. Side effects are evil :)

option 2: IF YOU MUST, then apply destructive methods on the object that your function receives as a parameter:

def func(list1):
    list1 = list1[2:]
    list1.pop(0)
    list1.pop(0)
    print(list1)   # prints [2, 3]

list1 = [0, 1, 2, 3]
func(list1)
print(list1)       # prints [2, 3]

Upvotes: 1

Praxeolitic
Praxeolitic

Reputation: 24079

You've run into "pass by name". The code you show only changes what the "list1" name that is local to func() points to. If you use the "list1" name to change the value of what is being referred to, rather than pointing the "list1" name within func() to something else, then that will be seen by the rest of the program.

def func(list1):
    del list1[0:2]
    # list1 = list1[2:]
    # print(list1)   # prints [2, 3]

list1 = [0, 1, 2, 3]
func(list1)
print(list1)

Upvotes: 1

venpa
venpa

Reputation: 4318

You have to return and assign the returned value to list1:

def func(list1):
    list1 = list1[2:]    
    print(list1)   # prints [2, 3]
    return list1

list1=func(list1)

or you have to reference list1 as global inside func().

Upvotes: 5

falsetru
falsetru

Reputation: 369074

list1 = list[2:] will create a list and make the local variable reference the new list. It does not affect the original list.

Use list slice assignment to get what you want:

def func(list1):
    list1[:] = list1[2:]
    print(list1)   # prints [2, 3]

or make the function return the new list, and assign the return value in the calling part:

def func(list1):
    return list[2:]

list1 = [0, 1, 2, 3]
list1 = func(list1)
....

Upvotes: 2

Related Questions