Python|正确使用二维数组/列表
Python提供了许多创建二维列表/数组的方法。然而,人们必须知道这些方式之间的区别,因为它们会在代码中产生难以追踪的复杂性。让我们从创建以 0 初始化的大小为 N 的一维数组的常用方法开始。
方法 1a
Python3
Python3
Python3
Python3
Python3
Python3
Python3
Python3
方法 1b
Python3
扩展上述内容,我们可以通过以下方式定义二维数组。
方法 2a
Python3
方法 2b
Python3
方法 2c
Python3
到目前为止,这两种方式都给出了看似相同的输出。让我们更改方法 2a 和方法 2b 的数组中的一个元素。
Python3
我们希望只有第一行的第一个元素更改为 1,但在方法 2a 中每行的第一个元素都更改为 1。这种特殊的功能是因为Python使用我们将尝试理解的浅表。
在方法 1a 中, Python不会创建 5 个整数对象,而是仅创建一个整数对象,并且数组 arr 的所有索引都指向同一个 int 对象,如图所示。
如果我们将第 0 个索引分配给另一个整数,比如 1,则创建一个值为 1 的新整数对象,然后第 0 个索引现在指向这个新的 int 对象,如下所示
类似地,当我们创建一个二维数组为“arr = [[0]*cols]*rows”时,我们本质上是对上述类比的扩展。
1. 只创建一个整数对象。
2. 创建一个 1d 列表,它的所有索引都指向点 1 中的同一个 int 对象。
3. 现在,arr[0]、arr[1]、arr[2] ...。 arr[n-1] 都指向上面第 2 点中的同一个列表对象。
上面的设置可以在下图中可视化。
现在让我们将“arr”第一行中的第一个元素更改为
arr[0][0] = 1
=> arr[0] 指向我们上面创建的单个列表对象。(记住 arr[1], arr[2] …arr[n-1] 也都指向同一个列表对象)
=> arr[0][0] 的赋值将创建一个值为 1 的新 int 对象,并且 arr[0][0] 现在将指向这个新的 int 对象。(arr[1][0] 也是如此, arr[2][0] …arr[n-1][0])
这可以在下图中清楚地看到。
因此,当像这样创建 2d 数组时,更改某一行的值将影响所有行,因为数组的所有行都引用了一个整数对象和一个列表对象。
正如您所料,追踪由这种浅表使用引起的错误是很困难的。因此,声明二维数组的更好方法是
Python3
与方法 2a 不同,此方法创建 5 个单独的列表对象。检查这一点的一种方法是使用“is”运算符来检查两个操作数是否引用同一个对象。