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

发表于:2022-12-08 09:44

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:宇宙之一粟    来源:稀土掘金

#
Python
分享:
  前言
  Python 提供了许多方法来创建二维列表/数组。然而,但大多数人不知道这些创建方法的区别。我也不知道,所以本文就来介绍一下关于二维数组的有趣地方。
  创建一维数组/列表
  先让我们先来看看创建大小为 N、初始化值为 0 的一维数组(列表)的常见方法。
  原始方法
  array1 = [0] * 5
  array1
  [0, 0, 0, 0, 0]
  用列表推导式
  array2 = [0 for i in range(5)]
  array2
  [0, 0, 0, 0, 0]
  在 Python3 的 IDLE 操作如下:
  创建二维数组
  二维数组是一个线性存储在内存中的二维数据结构。这意味着它有两个维度,行和列,因此它也代表一个矩阵。
  通过线性数据结构,我们的意思是元素被线性地放置在内存中,并且每个元素都与它的上一个和下一个元素相连。
  如果我们把二维数组想象成表格的形式,但实际上,元素是线性地存储在内存中的。二维数组的元素在内存中是连续排列的。这意味着,如果一个元素出现在当前的内存地址,那么下一个元素将被放置在下一个内存地址。这种类型的存储使数组可以随机访问。这意味着我们可以独立访问数组中的任何元素。就像下图:
  在 Python 中创建二维数组,不像 C++ 和 Java 中那样简单,直接用两个 [][] 中括号。先来看一下 Java 中创建二维数组的方式。
  先来看 Java 中创建二维数组的方式,Java 中创建二维数组的格式:
  type arrayName[][];
  type [][]arrayName;
  比如,定义一个 4 行 2 列的整型二维数组:
  int[][] arrayName = new int[4][2]; // // 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)
  输出:
  [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
  所以,为了创建一个二维数组,其本质就是用嵌套类别的方式,就像下面这样:
  >>> li = [[1,2,3], [4,5,6]]
  >>> li
  [[1, 2, 3], [4, 5, 6]]
  这样又太麻烦,我想有没有更好的方法。
  方法一
  像创建一维数组那样:
  >>> rows, cols = (2, 3)
  >>> arr = [[0] * cols] * rows
  >>> arr
  [[0, 0, 0], [0, 0, 0]]
  方法二
  利用列表推导式:
  >>> arr = [[0 for i in range(cols)] for j in range(rows)]
  >>> arr
  [[0, 0, 0], [0, 0, 0]]
  两种方式都提供与现在相同的输出。
  更改一下二维数组的元素看看
  之前说过,这种方式不一定能满足你对二维数组的期望,现在让我们更改方法一和方法二的数组中的元素:
  # 方法一
  >>> rows, cols = (2, 3)
  >>> arr = [[0] * cols] * rows
  >>> arr[0][0] = 1
  >>> for row in arr:
  ...     print(row)
  ...
  [1, 0, 0]
  [1, 0, 0]
  奇怪的事情发生了,明明我只改变了 arr[0][0],我希望的是第一行的第一个元素更改为 1,但结果却是每行的第一个元素更改为 1。
  再来看一下方法二:
  # 方法二
  >>> rows, cols = (2, 3)
  >>> arr = [[0 for i in range(cols)] for j in range(rows)]
  >>> arr[0][0] = 1
  >>> for row in arr:
  ...     print(row)
  ...
  [1, 0, 0]
  [0, 0, 0]
  方法二正是我想要的答案。
  什么原因呢?
  我这里就简单解释一下:
  方法一中,Python 不会创建 2 个 list 对象,而是仅创建一个 list 对象,并且数组 arr 的所有索引都指向同一列表对象( list ),如图所示。
  方法二,会创建 2 个单独的列表对象,如下图:
  我们可以通过 is() 函数来检查上面的方法一和方法二是否指向同一个对象:
  可以看到通过方法二创建的数组 arr1[0] 和 arr1[1] 结果为 False。
  >>> rows, cols = (5, 5)
  >>> arr1 = [[0 for i in range(cols)] for j in range(rows)]
  >>> print(arr1[0] is arr1[1])
  False
  而方法一结果为 True,说明是同一对象。
  >>> arr2 = [[0]*cols]*rows
  >>> print(arr2[0] is arr2[1])
  True
  所以正确的创建二维数组的方式就是用方法二,  也就是:
  rows, cols = (5, 5)
  arr2 = [[0 for i in range(cols)] for j in range(rows)]
  一个 5 行 5 列的二维数组就创建成功:
  >>> for row in arr2:
  ...     print(row)
  ...
  [0, 0, 0, 0, 0]
  [0, 0, 0, 0, 0]
  [0, 0, 0, 0, 0]
  [0, 0, 0, 0, 0]
  [0, 0, 0, 0, 0]
  不过,还没完,还有一点,我们发现 i 和 j 变量好像都没使用,所以我们用单下划线 _ 进行变量舍弃:
  rows, cols = (5, 5)
  arr2 = [[0 for _ in range(cols)] for _ in range(rows)] # 创建一个正确的5行5列的数组
  在 Python 中,单个独立下划线是用作一个名字,来表示某个变量是临时的或无关紧要的。
  方法三
  最后,如果想要一个支持数学运算的二维数组,推荐使用 numpy 包。官网点此处。
  numpy 中的矩阵操作最常使用的是二维数组类型。有很多方法可以创建一个新的数组;其中最有用的是 zeros 函数,它接受一个形状参数并返回一个给定形状的数组,其值被初始化为零。
  >>> import numpy
  >>> numpy.zeros(5,5)
  array([[0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0.]])
  >>>
  >>> numpy.empty((5,5)) # allocate, but don't initialize
  array([[0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0.]])
  >>>
  >>> numpy.ones((5,5)) # initialize with ones
  array([[1., 1., 1., 1., 1.],
         [1., 1., 1., 1., 1.],
         [1., 1., 1., 1., 1.],
         [1., 1., 1., 1., 1.],
         [1., 1., 1., 1., 1.]])
  总结
  本文的创造灵感来自于学习 Python 的列表时,想到 Java 中的数组和二维数组,就想上网搜搜 Python 二维数组的定义方式,然后就找到了 StackOverflow 上的这一个问题:How to define a two-dimensional array?,在这个问题的回答下,抱着玩一玩的心态写完了这篇文章
  至此,我们终于能够正确创建一个 Python 的二维数组了。对,就是它:
  arr2 = [[0 for _ in range(5)] for _ in range(5)]  # 创建一个正确的5行5列的数组
  本文介绍了 Python 中的二维数组的三种创建方式,我们都知道数组是线性数据结构,包含了连续内存空间中相同数据类型的元素,所以我们能很方便的检索到数组中的每一个值,二维数组也不例外。通过 arr[row][cols] 能很方便的获取二维数组中的元素。
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号