51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 680|回复: 0
打印 上一主题 下一主题

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

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-12-13 15:46:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 草帽路飞UU 于 2022-12-13 15:47 编辑

前言

  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

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-9-20 00:40 , Processed in 0.078986 second(s), 25 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表