繁体   English   中英

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

[英]python list mutation (for in loop vs range(len))

为什么下面没有改变传入的列表:

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

而这确实会改变它:

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

第一个只给你迭代变量( 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

有关详细信息,请参阅此文章

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

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

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

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

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

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

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

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

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

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

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

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 2中x的步骤名称边值侧代码1 x 1 x 2 x = x * 2 3.在listarg中x为x x 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

希望这可以帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM