How to modify a list within a Python method?

Asked

Viewed 390 times

0

Suppose I have the following method and the following list:

def ModificaValores(Valores):
      dados = [6,5,4,3,2,1,0]

      Valores = dados

Valores = [0,1,2,3,4,5,6]

print(Valores)
ModificaValores(Valores)
print(Valores)

Because on the way out I have the following result:

[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6]

If I modify element by element it works, but not like this. Explain to me why it happens!

1 answer

1


It doesn’t work because the changes made within the scope of the function are not loaded into the external scope - nor should it, as this could generate side effects and make it very difficult to maintain the code. I mean, don’t do it unless it actually makes sense.

Let’s go in pieces.

Outside the function, in the global scope, you define the list Valores. At this time, the object Valores shall have a unique identifier representing it that can be obtained via id(Valores). In Cpython, this value represents the memory address of your object. This object is passed via parameter to the function ModificaValores and, as in Python the type list is a changeable type, the object will be passed by reference, which implies that within the function will be the same object that was created outside, with the same values and same memory address. The fact that it is passed via reference explains why it reflects the changes made element by element, as you are only modifying the object. Even if this reflects the changes to the external scope, it should be used with great caution, only in cases that really make sense. Overall, the ideal would be to return a new list and assign it to the desired object. Something like:

def ModificaValores(Valores):
    # Neste caso o parâmetro é desnecessário
    # mas mantive por questões didáticas
    dados = [6,5,4,3,2,1,0]
    return dados

Valores = [0,1,2,3,4,5,6]

print(Valores)
Valores = ModificaValores(Valores)
print(Valores)

See working on Ideone | Repl.it

And why doesn’t it work when you assign the new list?

For you, when you define dados being a new list, defines a new object in memory, with a new address, which will exist only in the scope of the function. When you assign dados for Valores, you break the reference that Valores had with the external object and passes to reference the object dados local, but this change is made in the local scope, not being reflected to the external scope - in other words, you have an object Valores in the global scope and other in the local scope, being different from each other. The modifications you make in Valores, in the local scope, will not be reflected in Valores of the global scope, as they are different objects.

  • Very good your reply, thank you for the quick reply! But now in case I need to modify the list as in my example, is there any way to do that? It’s because I need to return True or False, and modify a list.

  • Another piece of bold was missing, but I commented that you can do this if it really makes sense. It is not wrong, only that if used improperly, it can generate side effects difficult to recognize. If your function really needs to change the object, you can do.

  • I saw that you said I can use it if I really need to, but is there any way to make a direct copy of another list? Instead of modifying element by element?

  • Apparently you need to change all the elements of the list, is that it? Maybe this is a XY problem, in which you ask for help in a solution that is possibly not the most appropriate. Why you need to change all the elements and still return a boolean?

  • That’s right, in the global scope I have a list called Bufferrx that I need to modify inside the serial reading with the received data, and return a True or False to inform if the data came correct and according to the communication protocol created!

  • @Filipesantos If you want, access the chat Stack Burst, but I think that changing the list in the global scope, in that case, is not the best solution.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.