草帽路飞UU 发表于 2022-12-13 15:46:46

二维数组创建方式的有趣之处在Python中

本帖最后由 草帽路飞UU 于 2022-12-13 15:47 编辑

前言

  Python 提供了许多方法来创建二维列表/数组。然而,但大多数人不知道这些创建方法的区别。我也不知道,所以本文就来介绍一下关于二维数组的有趣地方。

  创建一维数组/列表
  先让我们先来看看创建大小为 N、初始化值为 0 的一维数组(列表)的常见方法。

  原始方法

  array1 = * 5

  array1

  



  用列表推导式

  array2 =

  array2

  



  在 Python3 的 IDLE 操作如下:



创建二维数组

  二维数组是一个线性存储在内存中的二维数据结构。这意味着它有两个维度,行和列,因此它也代表一个矩阵。

  通过线性数据结构,我们的意思是元素被线性地放置在内存中,并且每个元素都与它的上一个和下一个元素相连。




如果我们把二维数组想象成表格的形式,但实际上,元素是线性地存储在内存中的。二维数组的元素在内存中是连续排列的。这意味着,如果一个元素出现在当前的内存地址,那么下一个元素将被放置在下一


个内存地址。这种类型的存储使数组可以随机访问。这意味着我们可以独立访问数组中的任何元素。就像下图:




在 Python 中创建二维数组,不像 C++ 和 Java 中那样简单,直接用两个 [][] 中括号。先来看一下 Java 中创建二维数组的方式。

  先来看 Java 中创建二维数组的方式,Java 中创建二维数组的格式:

  type arrayName[][];

  type [][]arrayName;



  比如,定义一个 4 行 2 列的整型二维数组:

  int[][] arrayName = new int; // // 2D integer array with 4 rows and 2 columns

  创建一个 Python 二维数组的错误

  也想模仿一下 Java,奈何只能得到一个语法错误:

  >>> twoD_array = [][]

      SyntaxError: invalid syntax



  抱歉,行不通。但是可以这样:

  >>> twoD_array = [[]]

  >>> twoD_array

  [[]]



  就像下图:




但这种方式不一一定符合你对二维数组的期望,后面会介绍。如果想要以一种更像 Java 的方式,可以使用这种方式:

  matrix = []

  for i in range(5):

  row = []

  for j in range(5):

      row.append(0)

  matrix.append(row)

  print(matrix)



  输出:

  [, , , , ]

  所以,为了创建一个二维数组,其本质就是用嵌套类别的方式,就像下面这样:

  >>> li = [, ]

  >>> li

  [, ]



  这样又太麻烦,我想有没有更好的方法。

  方法一

  像创建一维数组那样:

  >>> rows, cols = (2, 3)

  >>> arr = [ * cols] * rows

  >>> arr

  [, ]



  方法二

  利用列表推导式:

  >>> arr = [ for j in range(rows)]

  >>> arr

  [, ]



  两种方式都提供与现在相同的输出。

  更改一下二维数组的元素看看

  之前说过,这种方式不一定能满足你对二维数组的期望,现在让我们更改方法一和方法二的数组中的元素:

  # 方法一

  >>> rows, cols = (2, 3)

  >>> arr = [ * cols] * rows

  >>> arr = 1

  >>> for row in arr:

  ...   print(row)

  ...

  

  



  奇怪的事情发生了,明明我只改变了 arr,我希望的是第一行的第一个元素更改为 1,但结果却是每行的第一个元素更改为 1。

  再来看一下方法二:

  # 方法二

  >>> rows, cols = (2, 3)

  >>> arr = [ for j in range(rows)]

  >>> arr = 1

  >>> for row in arr:

  ...   print(row)

  ...

  

  



  方法二正是我想要的答案。

  什么原因呢?

  我这里就简单解释一下:

  方法一中,Python 不会创建 2 个 list 对象,而是仅创建一个 list 对象,并且数组 arr 的所有索引都指向同一列表对象( list ),如图所示。





方法二,会创建 2 个单独的列表对象,如下图:




我们可以通过 is() 函数来检查上面的方法一和方法二是否指向同一个对象:

  可以看到通过方法二创建的数组 arr1 和 arr1 结果为 False。

  >>> rows, cols = (5, 5)

  >>> arr1 = [ for j in range(rows)]

  >>> print(arr1 is arr1)

  False



  而方法一结果为 True,说明是同一对象。

  >>> arr2 = [*cols]*rows

  >>> print(arr2 is arr2)

  True



  所以正确的创建二维数组的方式就是用方法二,也就是:


  rows, cols = (5, 5)

  arr2 = [ for j in range(rows)]



  一个 5 行 5 列的二维数组就创建成功:

  >>> for row in arr2:

  ...   print(row)

  ...


  

  

  

  

  



  不过,还没完,还有一点,我们发现 i 和 j 变量好像都没使用,所以我们用单下划线 _ 进行变量舍弃:

  rows, cols = (5, 5)

  arr2 = [ for _ in range(rows)] # 创建一个正确的5行5列的数组


  在 Python 中,单个独立下划线是用作一个名字,来表示某个变量是临时的或无关紧要的。

  方法三

  最后,如果想要一个支持数学运算的二维数组,推荐使用 numpy 包。官网点此处。

  numpy 中的矩阵操作最常使用的是二维数组类型。有很多方法可以创建一个新的数组;其中最有用的是 zeros 函数,它接受一个形状参数并返回一个给定形状的数组,其值被初始化为零。

  >>> import numpy

  >>> numpy.zeros(5,5)

  array([,

         ,

         ,

         ,

         ])

  >>>

  >>> numpy.empty((5,5)) # allocate, but don't initialize

  array([,

         ,

         ,

         ,

         ])

  >>>

  >>> numpy.ones((5,5)) # initialize with ones

  array([,

         ,

         ,

         ,

         ])



  总结

  本文的创造灵感来自于学习 Python 的列表时,想到 Java 中的数组和二维数组,就想上网搜搜 Python 二维数组的定义方式,然后就找到了 StackOverflow 上的这一个问题:How to define a two-

dimensional array?,在这个问题的回答下,抱着玩一玩的心态写完了这篇文章。

  至此,我们终于能够正确创建一个 Python 的二维数组了。对,就是它:

  arr2 = [ for _ in range(5)]# 创建一个正确的5行5列的数组

  本文介绍了 Python 中的二维数组的三种创建方式,我们都知道数组是线性数据结构,包含了连续内存空间中相同数据类型的元素,所以我们能很方便的检索到数组中的每一个值,二维数组也不例外。通

过 arr 能很方便的获取二维数组中的元素。







页: [1]
查看完整版本: 二维数组创建方式的有趣之处在Python中