Self-study Python Fish-C Note-5 P20-P26 (part2)

python 中的列表 Part 2

本文主要讲解了python中列表的使用
本文为自学B站上鱼C的python课程随手做的笔记。
如有问题,欢迎大家批评指正
原视频链接:https://www.bilibili.com/video/BV1c4411e77t?p=8


一. 浅拷贝和深拷贝

(介绍顺序为从0开始理解向,从问题开始最后会说到两者区分)

1. is (is operator, 同一性运算符)

作用:用于检验两个变量是否指向同一个对象的一个运算符。
示例:
请添加图片描述
NB:出现以上情况是因为python对于不同对象的存储机制是不一样的。
对于字符串,由于字符串是不可变的,存储时是在内存中开辟一个位置来存放就好。如果有多个变量名指向一个字符串,那么两者的关系应是:请添加图片描述
对于列表,列表是可变的,尽管例子中x,y两个列表是一样的,但是python还是需要为它们开辟出两个不同的位置来存放,即:
请添加图片描述

2. 一个常见的创建多维列表的错误

导致改了多维列表中一个列表中的元素,其他列表的元素都发生了改动。
演示:
先用创建A,B两个看似相同的多维列表:
请添加图片描述
对多维列表中的一个元素进行修改:
请添加图片描述
我们发现,A按照我们的想法只改动了一个元素,但是B却每一维的第二个元素都发生了变化。
我们用is来判断一下:
请添加图片描述
所以A中的三维的三个列表是分别存储的三个不同列表,B中的是同一个列表的多次引用。即二者的在python中的内存布局应该是:
请添加图片描述
B试图通过乘号对列表进行拷贝,但事实上只是拷贝了同一个列表的引用。

3. 变量不是盒子 (Variables are not boxes)

变量不是一个盒子,当赋值运算发生的时候,python并不是将数据放到变量里去,而是将变量与数据进行挂钩,这个行为我们称之为引用。将一个变量赋值给另一个变量就是将一个变量的引用传递给另一个变量。请添加图片描述
我们发现通过赋值产生的两个列表,当x发生变化时,y也会改变。
两者内存示意图:

请添加图片描述
所以要想得到两个独立的列表,就需要用拷贝。

4. 浅拷贝和深拷贝 shallow and deep copy

  1. 浅拷贝:可以调用列表的copy方法,或者使用切片的方式来实现。
    示例:
    请添加图片描述

此时改变x,y并不会发生改变。这里copy方法拷贝的是整个列表对象,而不仅仅是引用。
示意图:
请添加图片描述

NB: 浅拷贝只是拷贝了外层的对象,如果包含嵌套对象的话,那么拷贝的只是其引用。所以在拷贝多维列表时,浅拷贝就可能出现问题,而深拷贝可以解决这个问题。
(浅拷贝处理一维列表是没有问题的)
示例,处理多维列表时,浅拷贝会出现的问题: 请添加图片描述
请添加图片描述

2. 深拷贝:
深拷贝在将原对象拷贝以后,也将对象中所有引用的子对象一并进行了拷贝。
深拷贝需要借助copy模块里的deepcopy函数。

5. copy模块

(1)copy 函数 (浅拷贝)
可以拷贝列表、字符串、元组等:
copy 实现浅拷贝:
请添加图片描述

(2)deepcopy 函数 (深拷贝)
deepcopy 实现深拷贝:
请添加图片描述
这里的深拷贝内存示意图:
请添加图片描述

二. 列表推导式 (list comprehension expression)

(1)基本语法

  1. a. 基本的一个for循环
[expression for target in iterable]

(1)示例:
请添加图片描述
理解:for循环的语句每次循环都有一个i,列表最终存放的元素取决于for循环语句左侧的expression表达式。 比如以list3为例,for循环把字符串“abcde”中每个字母拿出来,然后列表最终存放的元素是表达式i*2,即每个字母重复一次
(2)更多示例 (嵌套列表):
请添加图片描述
用列表推导式生成嵌套列表:请添加图片描述
2. b. 添加一个用于筛选的if分句

[expression for target in iterable if condition]

示例:
请添加图片描述
执行顺序:
请添加图片描述
应该是先执行for语句,再if,最后再i
比如下面这个例子验证执行顺序:
请添加图片描述
处理字符串:
请添加图片描述
3. c. 列表推导式实现嵌套

 [expression for target1 in iterable1
             for target2 in interable2
             ....
             for targetN in interableN]

示例:
请添加图片描述
注意外层循环放在前面,嵌套内层循环放在后面。
请添加图片描述
4. d. 列表推导式实行多个嵌套且每个for语句都可以加一个if 条件

[expression for target1 in iterable1 if condition1
                     for target2 in iterable2 if condition2
                     ......
                     for targetN in iterableN if conditionN]

请添加图片描述

(2) 列表推导式和for 循环的差别:
请添加图片描述
for 和列表推导式这里都产生了相同的列表,但是两者本质上有区别:
for: 是通过迭代来逐个修改列表里的元素(电视坏了,我们选择去修一下)
列表推导式:直接产生一个新的列表,再赋值回原先的变量名(电视坏了,直接换一个电视)
两者效果多相同,但本质上是不同的。for循环要比列表推导式运算速度上慢很多。

(3) 程序设计要注意KISS(keep it simple and stupid) 原则,列表推导式的复杂程度要好好把握。不要写太复杂的代码不便于维护,简洁胜于复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值