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

    # 对序列使用+和*
    # 通常+两侧的序列由相同类型的数据所构成,在拼接的过程中,两个被操作的序列都不会被修改,Python会新建一个包含同样类型数据的序列来作为拼接的结果
    # 如果想把一个序列复制几份然后再拼接起来,更快捷的做法是把这个序列乘以一个整数.同样,这个操作会产生一个新的序列:
    l1 = [1, 2, 3]
    print(l1 * 5)
    # +和*都遵循这个规律,不修改原有的操作对象,而是构建一个全新的序列
    # 注意:如果在a*n这个语句中,序列a里的元素是对其他可变对象的引用的话,这个式子的结果可能会出乎意料
    l2 = [l1]
    l3 = l2 * 3
    print(l3)  # [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
    l1[0] = 4
    print(l3)  # [[4, 2, 3], [4, 2, 3], [4, 2, 3]]
    
    # 建立由列表组成的列表
    # 有时我们会需要初始化一个嵌套着几个列表的列表,譬如一个列表可能需要用来存放不同的学生名单,或者一个井字游戏板上的一行方块.
    # 想要达成这些目的,最好的选择是使用列表推导式
    board = [["_"] * 3 for i in range(3)]
    print(board)  # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
    board[1][2] = "X"
    print(board)  # [['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']]
    
    # 下面展示一种看起来很好,但是错误的方法
    weird_board = [["_"] * 3] * 3
    print(weird_board)  # [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
    weird_board[1][2] = "O"
    print(weird_board)  # [['_', '_', 'O'], ['_', '_', 'O'], ['_', '_', 'O']]
    # 外面的列表其实包含3个指向同一个列表的引用,一旦我们视图标记第一行第二列的元素,就立马暴露了列表内3个引用指向同一个对象的事实
    
    
    # 序列的增量赋值
    # 增量运算符+=和*=的表现取决于它们的第一个操作对象.
    # +=背后的特殊方法是__iadd__(用于"就地加法"),但是如果一个类没有实现这个方法,Python会退一步调用__add__
    a = [1, 2, 3]
    b = [4, 5, 6]
    a += b
    # 如果a实现了__iadd__方法,就会调用这个方法.同时对可变序列来说,a会就地该表.就像调用了a.extend(b)一样.
    # 但是如果a没有实现__iadd__方法,a += b这个表达式的效果就变得跟a = a + b一样了.
    # 也就是说,在这个表达式中,变量名会不会被关联到新的对象,完全取决于这个类型有没有实现__iadd__方法.
    # 总的来说,可变序列一般都实现了__iadd__方法,因此+=是就地加法.
    # 这个概念也适用于*=,不同的是,*=相对应是__imul__方法.
    
    # 下面这个小例子,展示的是*=在可变和不可变序列上的作用
    l4 = [1, 2, 2]
    print(id(l4))  # 2534218951304
    l4 *= 2
    print(id(l4))  # 2534218951304
    t = (1, 2, 3)
    print(id(t))   # 2535959527360
    t *= 2
    print(id(t))   # 2534198634440
    # 对不可变序列进行重复拼接操作的话,效率会低很多,因为每次都有一个新对象,而解释器需要把原来对象中的元素先复制到新的对象里,然后再追加新的元素.
    # str是一个例外,因为对字符串做+=操作实在是太普遍了,所以CPython对它做了优化.为str初始化内存的时候,程序会为它留出额外的可拓展空间,因此进行增量操作的时候,
    # 并不会涉及复制原有字符串到新位置这类操作.
    
    # 一个关于+=的谜题
    t = (1, 2, [30, 40])
    t[2] += [50, 60]
    # 这两个表达式到底会产生什么结果?
    # A: t变成(1,2,[30,40,50,60])
    # B: 因为tuple不支持对它的元素赋值,所以会排除TypeError异常
    # C: 以上两个都不是
    # D: a和b都是对的
    
    
  • 相关阅读:
    web测试知识点整理
    LINUX系统、磁盘与进程的相关命令
    压缩与解压
    LINUX基本操作命令
    linux命令管道工作原理与使用方法
    C#根据path文件地址进行下载
    C#向Word文档中的书签赋值
    网站发布
    乱码转换
    获取新增的数据ID
  • 原文地址:https://www.cnblogs.com/zyyhxbs/p/13141569.html
Copyright © 2011-2022 走看看