for循环中的Python就地对象更新
在Python>=3.5中:for循环中的Python就地对象更新,python,python-3.x,numpy,Python,Python 3.x,Numpy,在Python>=3.5中: x = np.zeros((2,3)) for x_e in x: x_e += 123 此操作返回所有123的2x3矩阵。鉴于以下内容返回全零: x = np.zeros((2,3)) for x_e in x: x_e = 123 这对我来说有点令人不快,因为x_e是x中的一个元素,而且感觉不到x正在被更新 好吧,我认为这是一件事,它被称为“就地”更新?(类似于就地算法?) 但是,令人不安的是,这不适用于列表: x = [0,0,0] for
x = np.zeros((2,3))
for x_e in x:
x_e += 123
此操作返回所有123
的2x3
矩阵。鉴于以下内容返回全零:
x = np.zeros((2,3))
for x_e in x:
x_e = 123
这对我来说有点令人不快,因为x_e
是x
中的一个元素,而且感觉不到x
正在被更新
好吧,我认为这是一件事,它被称为“就地”更新?(类似于就地算法?)
但是,令人不安的是,这不适用于列表:
x = [0,0,0]
for x_e in x:
x_e += 123
这将返回列表
[0, 0, 0]
如果有人能告诉我这里到底发生了什么,我将不胜感激 想象一下你有:
>>> x = np.array(range(5))
>>> x
array([0, 1, 2, 3, 4])
所以现在:
>>> x+123
array([123, 124, 125, 126, 127])
正如您所看到的,“+”操作被映射到数组。所以当你这么做的时候
创建一个满是0的数组,并将123添加到该数组所包含的子列表中,这样才能得到上述结果。在第一个代码段中,您对
ndarray
对象执行就地添加。由于每个x_e
都是ndarray
,因此就地操作将成功并更改元素
在第二个代码段中,您只是重新分配到循环变量。对x
的元素不执行任何操作
在第三个代码段中,您没有多维列表,因此每个xue
实际上是一个int
。在int
上使用+=
不会原地更改,它会返回一个新的整数对象(您不存储该对象)
以下内容可能与第一个更相关:
x = [[0, 0, 0] for _ in range(3)]
for x_e in x:
x_e += [123]
这里,x
的每个元素都是一个列表
对象[0,0,0]
,您可以在其上适当添加元素123
。执行后,x
将:
[[0, 0, 0, 123], [0, 0, 0, 123], [0, 0, 0, 123]]
是的,但是,为什么就地for循环操作不能与列表一起工作呢?对我来说,新的是for循环中的就地操作。我确实理解广播,因为我是从CemS来的。这是因为您正在为循环更改一个可变对象,该循环是主列表的子列表,而更改一个可变对象是对原始对象的引用,对它的任何更改都会影响原始对象。@CemS.,在python列表和numpy数组中是不同的。例如,列表与数组的另一大区别是,列表中的内置函数(如sum)的执行速度比数组快得多。我们只使用np.array来表示大的data@coder在这种情况下,它们是一样的,这只是易变性的问题,而不是它们的功能。@Kasramvd,是的,我同意我只是想澄清一下,一般情况下,列表和numpy数组并不总是一样的。可能的dup:,@Divakar,谢谢你的指点。但我相信他们没有回答关于整数不变性的第三点。另外,请相信我,当我在互联网上搜索答案时,我找不到它们。:)谢谢你的回答,这就是我想澄清的。但是,我可以问一下为什么我们不能在适当的位置更改
int
。因为int
对象是不可变的,语言设计者很早就做出了这个决定,因为它有很多好处。@Kasramvd,谢谢!这说明了这件事。