当前位置: 首页 > news >正文

Python 序列构成的数组(对序列使用+和_)

对序列使用+和*

Python 程序员会默认序列是支持 + 和 * 操作的。通常 + 号两侧的序列由
相同类型的数据所构成,在拼接的过程中,两个被操作的序列都不会被
修改,Python 会新建一个包含同样类型数据的序列来作为拼接的结果。

如果想要把一个序列复制几份然后再拼接起来,更快捷的做法是把这个
序列乘以一个整数。同样,这个操作会产生一个新序列:

>>> l = [1, 2, 3]
>>> l * 5
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> 5 * 'abcd'
'abcdabcdabcdabcdabcd'

+ 和 * 都遵循这个规律,不修改原有的操作对象,而是构建一个全新的
序列。

如果在 a * n 这个语句中,序列 a 里的元素是对其他可变
对象的引用的话,你就需要格外注意了,因为这个式子的结果可能
会出乎意料。比如,你想用 my_list = [[]] * 3 来初始化一个
由列表组成的列表,但是你得到的列表里包含的 3 个元素其实是 3
个引用,而且这 3 个引用指向的都是同一个列表。这可能不是你想
要的效果。

建立由列表组成的列表
有时我们会需要初始化一个嵌套着几个列表的列表,譬如一个列表可能
需要用来存放不同的学生名单,或者是一个井字游戏板 上的一行方
块。想要达成这些目的,最好的选择是使用列表推导,见示例 2-12。
示例 2-12 一个包含 3 个列表的列表,嵌套的 3 个列表各自有 3 个
元素来代表井字游戏的一行方块

>>> board = [['_'] * 3 for i in range(3)] ➊
>>> board
[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
>>> board[1][2] = 'X' ➋
>>> board
[['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']]

➊ 建立一个包含 3 个列表的列表,被包含的 3 个列表各自有 3 个元
素。打印出这个嵌套列表。
➋ 把第 1 行第 2 列的元素标记为 X,再打印出这个列表。
示例 2-13 展示了另一个方法,这个方法看上去是个诱人的捷径,但实
际上它是错的。

示例 2-13 含有 3 个指向同一对象的引用的列表是毫无用处的

>>> weird_board = [['_'] * 3] * 3 ➊
>>> weird_board
[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
>>> weird_board[1][2] = 'O' ➋
>>> weird_board
[['_', '_', 'O'], ['_', '_', 'O'], ['_', '_', 'O']]

➊ 外面的列表其实包含 3 个指向同一个列表的引用。当我们不做修改
的时候,看起来都还好。
➋ 一旦我们试图标记第 1 行第 2 列的元素,就立马暴露了列表内的 3
个引用指向同一个对象的事实。

示例 2-13 犯的错误本质上跟下面的代码犯的错误一样:

row=['_'] * 3
board = []
for i in range(3):
  board.append(row) ➊

➊ 追加同一个行对象(row)3 次到游戏板(board)。
相反,示例 2-12 中的方法等同于这样做:

>>> board = []
>>> for i in range(3):
... row=['_'] * 3 # ➊
... board.append(row)
...
>>> board
[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
>>> board[2][0] = 'X'
>>> board # ➋
[['_', '_', '_'], ['_', '_', '_'], ['X', '_', '_']]

➊ 每次迭代中都新建了一个列表,作为新的一行(row)追加到游戏板
(board)。
➋ 正如我们所期待的,只有第 2 行的元素被修改。

我们一直在说 + 和 *,但是别忘了我们还有 += 和 *=。随着目标序列的
可变性的变化,这个两个运算符的结果也大相径庭。

http://www.dtcms.com/a/98783.html

相关文章:

  • sqlmap基础命令总结
  • [C++] 智能指针 进阶
  • Mysql练习题
  • RPCGC阅读
  • 算法刷题记录——LeetCode篇(11.1) [第1001~1010题]
  • Linux进程管理之进程的概念、进程列表和详细的查看、进程各状态的含义
  • C 语言的未来:在变革中坚守核心价值
  • vue搭建一个树形菜单项目
  • 坚持“大客户战略”,昂瑞微深耕全球射频市场
  • 计算机网络 第二章:应用层(2)
  • 项目实战-角色列表
  • SQLAlchemy系列教程:事件驱动的数据库交互
  • vue3实现router路由
  • 用Python实现简易的命令行工具
  • 【Java集合夜话】第9篇下:深入剖析TreeMap源码:红黑树实现原理与面试总结(建议收藏)
  • day1_Flink基础
  • 【Git教程】将dev分支合并到master后,那么dev分支该如何处理
  • Promise使用
  • 【题解】AtCoder At_abc399_d [ABC399D] Switch Seats
  • .NET开发基础知识21-30
  • [GXYCTF2019]禁止套娃1 [GitHack] [无参数RCE]
  • Matplotlib基本使用
  • 数据库监控 | openGauss监控解析
  • 小程序API —— 56页面处理函数 - 下拉刷新
  • 前端常问的宏观“大”问题详解(二)
  • 编译原理课设工作日志
  • 一些练习 C 语言的小游戏
  • 探索Scala基础:融合函数式与面向对象编程的强大语言
  • 在 Unreal Engine 5 中制作类似《鬼泣5》这样的游戏时,角色在空中无法落地的问题可能由多种原因引起。
  • C++作用域辨识详解