Python list mutation (for in loop vs range (len))

why the following doesn't mutate the past in the list:

def modify(listarg):
    for x in listarg:
        x=x*2

      

whereas this mutates it:

def modify(listarg):
    for x in range(len(listarg)):
        listarg[x]=listarg[x]*2

      

+3


source to share


4 answers


The first, just gives you an iterated variable ( x

), essentially for...in

uses a built-in function iter

. In the second case, you are actually binding the value to the list.

for x in listarg:
  x=x*2

      

The code above can be seen as:



i = iter(listarg)
x = i.next() # fetch first value
# this value then you double
# which won't effect the element

      

You can find more information in the article.

+1


source


def modify(listarg):
    for x in listarg:
        x=x*2

      

Here x

is just a variable, it has nothing to do with the x

one you are repeating. It's like a letter:



def modify(listarg):
    for x in listarg:
        y=x*2

      

In your second code, you are trying to modify the list itself.

+1


source


The first one simply double-checks a variable named to an x

object whose value doubles the value of the current list item. It does nothing on the list.

The second modifies the list by directly assigning it to the elements.

Here's another way to change the list:

def modify(listarg):
  listarg[:] = [el * 2 for el in listarg]

      

It is important here [:]

; without it, we will create a new list instead of replacing the existing content.

0


source


It has to do with how variables are named in python (i.e. how memory works).

In the first case, you create a variable named x

. Over time, you reassign it to the value that is in the list. After assigning it a value from the list, you assign that value twice. At this point you are still talking about x

- you read a value from a list and assigned it x

and then assigned twice the x

value x

. So let's take a look at it with code:

def modify(listarg):
    for x in listarg:  # read a value from the list, and assign it as the value of the variable called x
        x=x*2  # x is now 2x

      

The main thing to keep in mind is that there is a namespace in memory and an in-memory space for values ​​(assuming listarg = [1,2]

):

side value of the side value of step name 1 x 1 for x in list 2.x 2 x = x * 2 3.x 2 for x in list 4. x 4 x = x * 2

So, you see, only the meaning changes x

. Never values ​​inlistarg

In the second case, you directly access the parts listarg

and change their values:

side value of the side value of the step name 1. listarg [1,2]
         x 0 for x in the range (len (listarg)) 2. x 0 listarg [2,2] listarg [x] = listarg [x] * 2

I'll stop tracking execution here to indicate:
You are accessing the 0th "compartment" (or index) listarg

and changing the value assigned to it. The value that is being executed listarg[x]

is changed, not the value of any other variable (for example x

)

Hope it helps

0


source







All Articles