python基础(七):短路运算、深浅copy

一、短路运算

短路运算涉及到了隐式布尔值和显示布尔值的区别,这个我在前面条件判断处就已经又说过:
https://blog.csdn.net/weixin_44571270/article/details/105673741

一般显式布尔值参与逻辑运算没有什么问题,得到的结果无非就是True或False这两种情况,当隐式布尔值参与逻辑运算,得到结果就可能不一样了,请看下面的实例:

我们都知道and两边都为真才为真,只要有一边为假就是假
在这里插入图片描述

15 > 10为真,因此不足以判断真假性,所以继续判断右边真假性,0、None、空为假,所以右边为假,所以整个条件判断为假,但为什么不显示False,而显示[],因为它是隐式布尔值。
2 > 10为假,可以判断真假性,为假,执行到显示布尔值为止,所以显示False。执行一半就停止了,我们称它短路了,即短路运算

总结:所有执行到显示布尔值就停止的,便显示True或False,所有执行到隐式布尔值就停止的,便显示其本身,虽然显示其本身,到还是False的意思。

复杂一点的例子:
在这里插入图片描述
None默认不显示任何值,需要打印才能看出来。

二、深浅copy存在的必要性

注意:深浅copy这种操作只存在于可变类型中,主要是为了解决可变类型数据的复制粘连问题。

a = [1,2,3,[1,2,3]]
b = a
a.clear()
print(a,b)
print(a is b)

在这里插入图片描述
一般的赋值复制,我们可以看到这样一个情况,对原列表进行操作,复制的列表也会被改变值,究其根本还是因为它们存储的是同一内存地址,这种复制的藕断丝连的情况我们不允许其出现。

二、浅copy

基于上述这种赋值复制的弊端,便出现了深浅copy。
接下来我先用列表对浅拷贝,进行剖析:

import copy
a = [1,2,3,[1,2,3]]
b = copy.copy(a)
print(id(a))
print(id(b))

在这里插入图片描述我们可以看到a和b已经不再指向同一个堆内存地址了。内存图解如下:

在这里插入图片描述现在我们再对列表中的内容进行赋值,不会再出现修改原列表内容,复制过后的列表内容也发生改变这种情况了。但是这种拷贝出来的列表也有局限性,列表中列表,或者说列表中如果存储着可变类型的数据,那么依旧存在粘连情况。请看下面代码:

import copy
a = [1,2,3,[1,2,3]]
b = copy.copy(a)
a[3][1] = 5
print(b,end=' ')
print(a[3] is b[3])
#执行结果[1, 2, 3, [1, 5, 3]] True

说明对列表中的列表中的内容进行操作时,还是会影响到复制的列表中的内容,因为两个列表中的索引3存储的列表的地址都是一样的。

我们所学的列表切片,也是一种浅copy:

a = [1,2,3,[1,2]]
b = a[:]
print(a[3] is b[3]) #执行结果为True

还有列表的copy方法也是浅复制。

浅copy总结:

  • 浅拷贝只能保证原列表和复制所得的列表的内存地址不同,列表中存储的各个索引对应的内存地址还是原模原样被复制到过去。
  • 浅拷贝当列表中存储的都是不可变类型时,原列表和复制所得的列表将是彻底的分割,没有任何粘连。

三、深copy

浅拷贝的缺点就是当遇到可变类型嵌套可变类型时,还是存在粘连现象,深拷贝,将会深度切断这些连接。让可变类型嵌套多少层可变类型,都是完全分开的。

接下来我将使用字典,讲解深copy:

import copy
a = {'a':1,'b':2,'c':[1,2]}
b = copy.deepcopy(a)
print(a['c'] is b['c']) #执行结果:False

内存图解如下:
在这里插入图片描述如内存图解所示,这样就没有粘连了,完全是两个独立的个体。
在这里我要再次强调下,不可变类型你是不能修改的,你只能重新创建一个新的内存空间存个新的变量值。所以也不会影响复制的字典里的内容。

深copy总结:

  • 浅copy在可变类型里全存不可变类型时和深copy效果一样
  • 深copy产生的复制的列表、字典等可变类型,是一个独立的个体,没有任何粘连

猜你喜欢

转载自blog.csdn.net/weixin_44571270/article/details/105822423
今日推荐