zoukankan      html  css  js  c++  java
  • 对序列使用+和*

    序列是支持 + 和 * 操作的。通常 + 号两侧的序列由 相同类型的数据所构成,在拼接的过程中,两个被操作的序列都不会被 修改,Python 会新建一个包含同样类型数据的序列来作为拼接的结果。 如果想要把一个序列复制几份然后再拼接起来,更快捷的做法是把这个 序列乘以一个整数。同样,这个操作会产生一个新序列:

    demo1

    In [1]: l = [1,2,3,4,5]
    
    In [2]: l = [1,2,3,4,5] * 3
    
    In [3]: l
    Out[3]: [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
    
    In [4]: 'abc' * 5
    Out[4]: 'abcabcabcabcabc'

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

    如果在 a * n 这个语句中,序列 a 里的元素是对其他可变 对象的引用的话,你就需要格外注意了,因为这个式子的结果可能 会出乎意料。

    比如,你想用 my_list = [[]] * 3 来初始化一个 由列表组成的列表,但是你得到的列表里包含的 3 个元素其实是 3 个引用,而且这 3 个引用指向的都是同一个列表。这可能不是你想要的效果。

    demo2

    In [16]: board = [['_'] * 3 for i in range(3)]      #1
    
    In [17]: board
    Out[17]: [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
    
    In [18]: board[1][2] = 'x'                          #2
    
    In [19]: board
    Out[19]: [['_', '_', '_'], ['_', '_', 'x'], ['_', '_', '_']]
    1.  建立一个包含 3 个列表的列表,被包含的 3 个列表各自有 3 个元 素。打印出这个嵌套列表。
    2.  把第 1 行第 2 列的元素标记为 X,再打印出这个列表。

      得到了我们期望的结果

    下面看demo3的方法,看似捷径,却是错误的:

    demo3

    In [25]: weied_board = [['_'] * 3] * 3       #1
    
    In [26]: weied_board
    Out[26]: [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
    
    In [27]: weied_board[1][2] = 'x'             #2
    
    In [28]: weied_board
    Out[28]: [['_', '_', 'x'], ['_', '_', 'x'], ['_', '_', 'x']]
    1.  外面的列表其实包含 3 个指向同一个列表的引用。当我们不做修改 的时候,看起来都还好。
    2. 一旦我们试图标记第 1 行第 2 列的元素,就立马暴露了列表内的 3 个引用指向同一个对象的事实。

      含有 3 个指向同一对象的引用的列表是毫无用处的

      demo3犯的错误本质上跟下面demo4的代码犯的错误一样:

    row=['_'] * 3
    board = []
    for i in range(3):
      board.append(row)    #1
    1. 追加同一个行对象(row)3 次到游戏板(board) 

    相反,正确的写法如下:

    In [1]: board = []
    
    In [2]: for i in range(3):
       ...:     row = ['_'] * 3            #1
       ...:     board.append(row)
       ...:
    
    In [3]: board
    Out[3]: [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
    
    In [4]: board[1][2] = 'x'
    
    In [5]: board                        #2
    Out[5]: [['_', '_', '_'], ['_', '_', 'x'], ['_', '_', '_']]
    1. 每次迭代中都新建了一个列表,作为新的一行(row)追加到游戏板 (board)。
    2. 正如我们所期待的,只有第 2 行的元素被修改。

    这里涉及到引用可变对象的原理陷进,下次我们再说

    积一时之跬步,臻千里之遥程
  • 相关阅读:
    python之re(正则表达式)
    virtualbox之下载地址
    数据库之sqlite
    vmware 虚拟机扩展 liunx系统硬盘空间
    常见python面试题-手写代码系列
    Python的Struct模块
    mac上安装brew如何加速
    outlook数字证书导出、导入及解决老是弹出macOS需要访问系统钥匙串弹窗问题
    docker命令学习
    Message from syslogd不停的打日志
  • 原文地址:https://www.cnblogs.com/wangbaojun/p/10614671.html
Copyright © 2011-2022 走看看