尝试在一个位置更改时,值在列表列表中的多个位置更改 [英] Value changing at multiple positions in a list of list when trying to change at one place

查看:119
本文介绍了尝试在一个位置更改时,值在列表列表中的多个位置更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下python代码:

The following Code in python:

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

似乎正在所有matrix[][1]个位置上改变值,矩阵变为 [[0,1,0],[0,1,0]]代替[[0,1,0],[0,0,0]].

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]].

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

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.

推荐答案

关于乘法运算符*如何在python中的列表上工作的方式有些细微之处.

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.

这可能可以澄清问题:

>>> 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 函数将返回对象的内存地址):

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]]

一种更彻底的替代方法是完全切换到 numpy ,它速度更快,并且从头开始考虑用于极快的矩阵和多维矢量操作,但也很难使用.

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!

这篇关于尝试在一个位置更改时,值在列表列表中的多个位置更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆