Python, clone lists

5

Be the code below:

def modif1(lista):
    lista = [4,5,6]
lista = [1,2,3]
modif1(lista)
print(lista) #resultado: [1,2,3]


def modif2(lista):
    lista[0] = 4
    lista[1] = 5
    lista[2] = 6
lista = [1,2,3]
modif2(lista)
print(lista) #resultado: [4,5,6]

def modif3(lista):
    lista[:] = [4,5,6]
lista = [1,2,3]
modif3(lista)
print(lista) #resultado: [4,5,6]

def modif4(lista):
    L = lista[:]
    L = [4,5,6]
lista = [1,2,3]
modif4(lista)
print(lista) #resultado: [1,2,3]

The modif1 function does not change the list because the scope of the function already has a variable with the name list.  The modif2 function modifies the list because it has no list name variable and access list (in scope global).  In function 3 comes the unexpected: when I do lista[:] am not making a clone of lista ? Why then when I modify lista[:] do I modify the original lista and not just the clone? This being the case, what changes modif4 of modif3 ?

    
asked by anonymous 12.02.2017 / 21:28

1 answer

8

In Python, everything is object. And parameters are passed by assignment (which more or less means that references to objects are passed by value). So if you make a change in the variable of lista it does not stay out of scope. As in your code, this also occurs in this simpler example:

def teste(a, b):
    a = 10
    b = 'Hello World!'

x = 1
y = 'Bla ble bli blo blu'
teste(x, y)
print(x, y) # Imprime: 1 Bla ble bli blo blu

It turns out that some objects are changeable , as is the case with lists. So when you do lista[0] , you are changing an element of the object (whose reference you received as a parameter), and so this change persists. The same goes for lista[:] . In this case you are changing several elements of the object instead of one. When you do lista = <qualquer coisa> , you have thrown away your original object and created a new one, in the local scope.

If you really want to make a copy of a list, use lista.copy :

def teste(lista):
    lista[0] = 99

lista = [i for i in range(10)]
teste(lista)
print(lista) # Imprime: 99, 1, 2, 3, 4, 5, 6, 7, 8, 9]

lista = [i for i in range(10)]
teste(lista.copy())
print(lista) # Imprime: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
12.02.2017 / 22:28