Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python列表变异(用于循环内vs范围(len))_Python_Arrays_Loops_For Loop - Fatal编程技术网

python列表变异(用于循环内vs范围(len))

python列表变异(用于循环内vs范围(len)),python,arrays,loops,for-loop,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 第一个简单地将名为x的变量重新绑定到一个对象,该对象的值是当前列表元素值的两倍。它对列表没有任何作用 第二种方法通过直接指定给列表的元素来修改列表

为什么下面的代码不改变传入列表:

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
的变量重新绑定到一个对象,该对象的值是当前列表元素值的两倍。它对列表没有任何作用

第二种方法通过直接指定给列表的元素来修改列表

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

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

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

第一个列表只提供迭代变量(
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
有关更多详细信息,请参阅此

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

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

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

这是因为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中x的1 x 1 2.x2x=x2 3.listarg中x的x 2 4.x4x=x2

因此,只有
x
的值被更改。切勿使用
listarg中的值

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

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

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


希望这有帮助

如果x只是一个变量,与我正在迭代的x无关,那么为什么如果我打印x,我会得到我正在迭代的x?因为当你这样做时,你只是打印
x
,而不是试图分配给它。当您尝试分配给它时,Python会自动区分您正在迭代的
x
和您正在分配给它的
x
。我一定是误解了for循环真正在迭代什么了。。。它似乎不是对列表对象的引用,而是一个副本。
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