[英]Python IndexError out of range after using for loop with range(len(list[:])-1)
[英]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.