为什么以下内容不会改变传入的列表:
def modify(listarg):
for x in listarg:
x=x*2
虽然这确实会改变它:
def modify(listarg):
for x in range(len(listarg)):
listarg[x]=listarg[x]*2
答案 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
)
希望这有帮助