当尝试在一个位置更改时,值会在列表列表中的多个位置发生变化

发布于 2024-12-17 14:40:36 字数 262 浏览 1 评论 0原文

python中的以下代码:

matrix = [[0]*3]*2
matrix[0][1] = 1

似乎正在改变所有第matrix[][1]位置的值,矩阵变成 [[0,1,0],[0,1,0]] 而不是 [[0,1,0],[0,0,0]]

这是变量初始化方式的问题还是 python 中的默认行为。

另外我如何一次只更改一个值。

The following Code in python:

matrix = [[0]*3]*2
matrix[0][1] = 1

seeems to be changing the value at all the matrix[][1]th positions, matrix becomes
[[0,1,0],[0,1,0]] instead of [[0,1,0],[0,0,0]].

Is this a problem with how the variable is initialised or is the default behaviour in python.

Also How do I change only one value at a time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痕至 2024-12-24 14:40:36

乘法运算符 * 在 Python 中的列表上的工作方式有一些微妙之处。

更一般地说,当应用于整数或字符串等不可变对象时,其效果与应用于列表和字典等可变对象时的效果有所不同。

这可能会澄清问题:

>>> l = [0] * 3  #a list of immutable integers
>>> l
[0, 0, 0]
>>> l[0] = 1
>>> l
[1, 0, 0]
>>> l = [[0]] * 3  #a list of mutable lists
>>> l
[[0], [0], [0]]
>>> l[0][0] = 1
>>> l
[[1], [1], [1]]

编辑(在评论中向@lazyr致敬) 在幕后,在这两种情况下 * 运算符都会创建具有相同标识的对象列表(内存地址),所以数组中的每个数字(和每个列表)实际上都是同一个对象,但是,不可变类型不能修改而只能替换,所以当你尝试为整数数组分配一个新值时,你实际上会替换整个对象,而这不是列表的情况。基于前面的示例(请记住 id 函数返回对象的内存地址):

>>> m = [1] * 3
>>> id(m[0])
39356344
>>> id(m[1])
39356344
>>> m[1] = 2
>>> id(m[1])
39356320  # new memory addres = different object!
>>> m = [[1]] * 3
>>> id(m[0])
40275408
>>> id(m[1])
40275408
>>> m[1][0] = 2
>>> id(m[1])
40275408  # same memory address = still the same object!

因此,在您的情况下,可能的解决方法是像这样初始化矩阵:

>>> matrix = [[0 for i in range(3)] for j in range(2)]
>>> matrix
[[0, 0, 0], [0, 0, 0]]
>>> matrix[0][2] = 1
>>> matrix
[[0, 1, 0], [0, 0, 0]]

另一种更激进的方法是完全切换到 numpy,速度更快,并且从头开始考虑快速的矩阵和多维向量操作,但也更难使用。

哈!

There are some subtleties on how the multiplication operator * works on lists in python.

More generally, there are differences on its effects when applied on immutable objects such integers or strings, and how those it has when applied on mutable objects like lists and dictionaries.

This might clarify the issue:

>>> l = [0] * 3  #a list of immutable integers
>>> l
[0, 0, 0]
>>> l[0] = 1
>>> l
[1, 0, 0]
>>> l = [[0]] * 3  #a list of mutable lists
>>> l
[[0], [0], [0]]
>>> l[0][0] = 1
>>> l
[[1], [1], [1]]

EDIT (kudos to @lazyr in the comments) Under the hood, in both cases the * operator creates a list of objects with the same identity (memory address), so each number (and each list) in the array are really the same object, however, immutable types can not be modified but only replaced, so when you try to assign a new value to the integer array, you will factually replace the entire object, while this is not the case with lists. Bulding on the previous example (keep in mind that the id function returns the object's memory address):

>>> m = [1] * 3
>>> id(m[0])
39356344
>>> id(m[1])
39356344
>>> m[1] = 2
>>> id(m[1])
39356320  # new memory addres = different object!
>>> m = [[1]] * 3
>>> id(m[0])
40275408
>>> id(m[1])
40275408
>>> m[1][0] = 2
>>> id(m[1])
40275408  # same memory address = still the same object!

So, in your case a possible workaround would be to initialise the matrix like this:

>>> matrix = [[0 for i in range(3)] for j in range(2)]
>>> matrix
[[0, 0, 0], [0, 0, 0]]
>>> matrix[0][2] = 1
>>> matrix
[[0, 1, 0], [0, 0, 0]]

An alternative - more radical - way would be to altogether switch to numpy, which is faster and thought from the ground up for extremely fast matrix and multidimensional vectors manipulation, but it is also harder to use.

HTH!

所谓喜欢 2024-12-24 14:40:36

尝试:

matrix = [[0]*3 for j in xrange(2)]

Try:

matrix = [[0]*3 for j in xrange(2)]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文