python列表变异(for in loop vs range(len))

时间:2014-12-14 13:49:23

标签: python arrays loops for-loop

为什么以下内容不会改变传入的列表:

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

虽然这确实会改变它:

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

4 个答案:

答案 0 :(得分:1)

第一个只为您提供迭代变量(x),基本上for...in使用内置iter函数。在第二种情况下,您实际将值绑定到列表。

for x in listarg:
  x=x*2

上面的代码可以看作:

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

有关详细信息,请参阅此article

答案 1 :(得分:1)

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

此处x只是一个变量,它与您正在迭代的x无关。这就像写作:

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

在第二段代码中,您尝试修改列表本身。

答案 2 :(得分:0)

第一个简单地将名为x的变量重新绑定到一个对象,该对象的值是当前列表元素值的两倍。它对列表没有任何作用。

第二个通过直接分配给它的元素来修改列表。

以下是修改列表的另一种方法:

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

在这里,[:]很重要;没有它,我们正在创建一个新列表,而不是替换现有列表的内容。

答案 3 :(得分:0)

这是因为在python中如何命名变量(即内存如何工作)。

在第一种情况下,您创建一个名为x的变量。随着时间的推移,您重复分配给它,列表中的任何值。从列表中为其分配值后,将其分配给该值两倍。此时,您仍在谈论x - 您已从列表中读取该值并将其分配给x,然后将x的值分配给{x 1}}。让我们看一下代码:

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

要记住的关键是内存中有一个名称空间,内存中有一个空格用于值(假设为listarg = [1,2]):

步骤名称边值侧码 listarg中x为1 x 1 2. x 2 x = x * 2 3. listarg中x为x 2 4. x 4 x = x * 2

所以你看,只有x的值被改变了。绝不是listarg

中的值

在第二种情况下,您将直接访问listarg的部分内容并更改其值:

步骤名称边值侧码 1. listarg [1,2]
           x 0表示范围内的x(len(listarg)) 2. x 0            listarg [2,2] listarg [x] = listarg [x] * 2

我将停止在这里追踪执行,以表明我的观点:
您正在访问listarg的第0个“隔离专区”(或索引)并修改分配给它的值。 listarg[x]保留的值正在更改,而不是某个其他变量的值(例如x

希望这有帮助