Skip to content

Latest commit

 

History

History
237 lines (166 loc) · 5.6 KB

091-192242-列表_加法_增强赋值_加等于_extend_扩展列表.sy.md

File metadata and controls

237 lines (166 loc) · 5.6 KB
show version enable_checker
step
1.0
true

列表 - 运算 - 列表相加

回忆

  • 上次研究了赋值运算
    • 直接用列表引用的地址赋值
      • 造成两个列表指向同一个对象
        • 一荣俱荣
        • 一损俱损
        • 所有操作都会作用到一个对象上
    • 如果将列表副本赋给变量
      • 这两个列表变量指向不同的对象
      • 互不影响
      • 制作副本的3种方法
        • copy拷贝
        • list构造
        • slice切片
  • 赋值运算符号=很简单
    • 但是由于等号右边的对象不同
    • 还是有很多细节的
  • 还有什么好玩的细节呢?
  • 列表可以做加法吗?🤔
    • 比如l1 + l2

图片描述

回忆字符串

图片描述

  • 字符串可以进行加法和乘法的运算
  • 列表也能做加法吗?

列表加法

图片描述

  • 再试试字符串列表

加法运算

  • 加是可以加的

图片描述

  • 但是加的结果
    • 没有赋给任何变量
    • 随着寄存器下次被赋值
    • 垃圾回收了
  • 没了

加法并赋值

图片描述

  • 把加法的结果赋给 l3
  • 那么这个加法的结果就有变量名进行引用了
  • 就不会被垃圾回收了
  • 什么是垃圾回收呢?

垃圾回收

  • 之前的语言

    • 分配和释放内存都是靠成员完成的
    • 容易忘记释放内存
    • 容易造成内存泄漏
    • 占用越来愈多
    • 最后崩溃
  • python 解释器

    • 定期观察分配给变量的空间
      • 是否还有变量在引用
    • getrefcount
    • 没有引用的话 就垃圾回收

图片描述

  • 垃圾回收
  • garage collection
  • l1、l2、l3 三个变量引用地址相同吗?

地址情况

  • 用id输出地址

图片描述

  • 这三个变量地址都不相同
    • 三块空间都有变量引用
    • 都不会被回收
  • 可以把列表求和的结果赋给 l1 么?

将列表之和赋给l1

图片描述

  • 赋值之后
    • l1 不再 指向原来的地址
    • 而是指向和的地址
  • l1 = l1 + l2
  • 是不是就是l1 += l2呢?

增强赋值运算

  • 从求和结果来看
    • l1 = l1 + l2
    • l1 += l2
    • 两者一致
  • += 也叫做 增强赋值运算
    • augmented assignment

图片描述

  • 但是从引用地址来看
    • += 会保留l1原来引用的地址
    • 而l1 = l1 + l2 中l1 获得一个新地址

图片描述

  • 这效果就很像对于切片赋值

切片赋值细节

  • 想要在列表尾部接出新列表
    • 首先要找到列表尾部的位置
    • 用len(a)得到a的长度为3
    • a[3:]就是尾部的空列表

图片描述

  • 这里使用切片 a[len(a):]
    • 其实就是在 a 的最后一个元素后面再追加列表 b
    • 然后 a 就是被扩展 extend 了

图片描述

  • 变量引用情况如何呢?

内存引用情况

  • 对l1尾部切片赋值

图片描述

  • 不会改变l1引用的地址
  • 这个时候其实有个新函数 extend

extend

图片描述

  • extend
    • 把参数里面的列表
    • 循环地放到extend方法的主体后面

图片描述

  • 有三种方式可以扩充列表
  • 并保留原来列表引用地址
    • l1 += l2
    • l1[-1:] = l2
    • l1.extend(l2)
  • 还有一种方式可以得到新的引用地址
    • l1 = l1 + l2
  • 效率如何呢?

效率

  • 加法运算效率最低
    • 是新建一个列表
    • 然后把 l1 的列表项都拿过来
    • 再把 l2 的列表项都拿过来
    • 最后把相加结果赋给 l1
  • 效率不如extend和切片赋值

图片描述

  • 那这个 extend 和 append
  • 有什么区别呢?

区别

  • 操作对象不同

图片描述

  • append
    • 是为原始列表添加新元素
    • 添加的是一个列表项
  • extend
    • 是用新列表扩展原始列表
    • 添加的是若干新元素

insert

  • 这三个函数都是插入列表项

图片描述

  • 有什么区别呢?

总结

  • 这次我们了解了列表的加法
  • 加法
    • 加法的本质是将两个列表拼接
    • 并将结果位置赋给帧(frame)上的变量来引用
  • 对于两个列表求和并赋值有4种做法
    • l1 = l1 + l2
    • l1 += l2
    • l1[-1:] = l2
    • l1.extend(l2)
  • 上述四种方法结果相同
    • 但是稍有区别
      • 第一种l1 = l1 + l2
        • 会改变l1 所引用的地址
        • 后三种不改变地址
      • 第四种l1.extend(l2)
        • 效率最高
        • 在当前列表位置后继续扩展列表

图片描述

  • 既然列表有加法
  • 那列表可以有乘法吗?🤔
  • 下次再说 👋