5. Python之条件判断和深浅copy
2021-01-10 本文已影响0人
随便写写咯
1. 条件
条件可以是比较运算
age = 18
print(age > 16) # 条件判断后会得到一个布尔值True, 显示布尔值
条件判断可以是True, False, 显示布尔值
is_beautiful = True
print(is_beautiful) >> True
隐式布尔值:所有的值都可以当成条件去用
0, None, 空为假(空字符串, 空列表, 空字典), 其余都为真
2. 逻辑运算符
逻辑运算: 根据逻辑运算的结果, 决定下一步操作
逻辑运算符: 把多个条件连接在一起
not, and, or
优先级: not > and > or
2.1 not
not就是把紧跟其后的那个条件结果取反, not与紧跟其后的条件是一个不可分割的整体
print(16 > 13) >> True
print(not 16 > 13) >> False # 16 > 13是True, 通过not取反, 结果为False
2.2 and
and: 逻辑与, and用来连接多个条件, 每个条件都为True, 最终结果才为True
print(10>3)
print( True and False)
print(True and 10 > 3 and 1 < 10)
>>
True
False
True
2.3 or
or: 逻辑或, or用来连接多个条件, 只要有一个为真, 结果为真, 所有结果为假, 结果才为假
如果是单独就只是一串and连接,或者单独一串or连接, 按照从左到右的顺序依次运算即可, and遇到假则停止, or遇到真则停止
如果是混用, 需要考虑优先级
3. 成员运算符
判断一个字符串是否存在于一个大字符串中
print("admin" in "hello admin") >> True
print("x" in "hello admin") >> False
成员运算符在判断字典时,看的是key不是value
print('x' in {"david":"xxx", "wang":"yyy", "admin":"zzzz"} )
>> False
not in: 不存在于xxx
print("admin" not in "hello admin")
>> False
4. 身份运算符
is: 判断的是id是否相等
5. if条件判断
语法1:
if 条件: # 条件表达式只需要能返回一个bool值即可, 可以使比较运算, 逻辑运算, 显示bool或者隐式bool
代码1 #缩进四个空格
代码2
代码3
语法2:
if 条件:
代码1
代码2
代码3
else:
代码1
代码2
代码3
语法3:
if 条件1:
代码1
代码2
代码3
elif 条件2:
代码1
代码2
代码3
elif 条件2:
代码1
代码2
代码3
语法4:
if 条件1:
代码1
代码2
代码3
elif 条件2:
代码1
代码2
代码3
elif 条件2:
代码1
代码2
代码3
...
else:
代码1
代码2
代码3
6. 短路运算
偷懒原则,偷懒到哪个位置,就把当前位置的值返回.
返回值可以是显示bool(True或者False), 也可以是隐式bool
2. 深浅copy
2.1 深浅copy引入
执行list2= list1的结果: # 这不叫copy, 而是变量赋值, 把list1指向的内存地址, 和list2做绑定
会在栈区中, 把list1的绑定的列表的内存地址, 绑定给list2, 此时list1和list2共同指向一块内存空间, 因此, 无论在list1还是在list2上对列表进行修改, 另一个列表都会受影响
结果就是两个列表无法独立分开, 也就是写操作无法独立
>>> list1 = ['dave','IT',[11,22]]
>>> list2 = list1
>>> list1[0] = 'jace'
>>> print(list1)
['jace', 'IT', [11, 22]]
>>> print(list2)
['jace', 'IT', [11, 22]]
图片.png
需求:
1、拷贝一下原列表产生一个新的列表
2、想让两个列表完全独立开,并且针对的是改操作的独立而不是读操作
2.2 如何copy列表
首先要知道, list2 = list1, 这不是copy, 只是变量的赋值
2.2.1 浅copy
list1=[
'dave',
'IT',
[11,22]
]
list3 = list1.copy()
print(list3)
['dave', 'IT', [11, 22]]
# 新的list3的列表的内存地址和list1不同, 说明.copy是浅copy, 会给新的列表开辟内存空间
print(id(list1))
print(id(list3))
>>
2695629813120
2695629626944
# 两个列表内部的索引对应的内存地址相同, 说明, 虽然生成了新的列表内存空间, 但是列表内的索引和内存地址对应关系,还是不变的
print(id(list1[0]),id(list1[1]),id(list1[2]))
print(id(list3[0]),id(list3[1]),id(list3[2]))
2323986184496 2323986184752 2323993114944
2323986184496 2323986184752 2323993114944
# 此时如果修改list1中不可变类型的值, 那么list3的值是不会跟着改变的
# 因为修改不可变类型是会产生新的值, 开辟新的内存空间, 那么list1列表中的0号和1号索引就会指向新的内存地址, 而list3的0号和1号索引不受影响, 还是指向原来的'dave'和'IT'的内存地址
list1=[
'dave',
'IT',
[11,22]
]
list3 = list1.copy()
print(list1) >> ['dave', 'IT', [11, 22]]
list1[0] = 'DAVE'
list1[1] = 'it'
print(list1) >> ['DAVE', 'it', [11,22]]
print(list3) >> ['dave', 'IT', [11, 22]]
# 如果修改list1中的可变类型, 列表[11,22], 那么list3的值会跟着改变
# 因为对于可变类型修改值, 并不会开辟新的内存空间, 而是在原有的空间基础上, 修改内部的原值
list1=[
'dave',
'IT',
[11,22]
]
list3 = list1.copy()
print(list1) >> ['dave', 'IT', [11, 22]]
list1[2][0] = 33
list1[2][1] = 44
print(list1) >> ['dave', 'IT', [33, 44]]
print(list3) >> ['dave', 'IT', [33, 44]]
总结:
浅copy:是把原列表第一层的内存地址不加区分完全copy一份给新列表, 这时新的列表的变量名会指向新的内存地址, 但是这个内存地址里面的内容还是和源列表一样的.
如果源列表中存的都是不可变类型, 比如整型, 字符串, 那么修改源列表的内容不会影响新的那个变量所绑定的列表. 因为对于不可变类型, 修改其变量赋值, 会开辟新的内容地址, 将源列表指向新的内存地址, 而后创建的列表还是指向没有修改的那些变量值.
浅拷贝, 对于不可变类型的写操作, 没有影响, 新的列表的值不会随着源列表的值的改变而改变. 可以实现写操作的独立. 但是对于可变类型, 比如列表, 字典, 由于修改列表, 字典的内容不会开辟新的内存地址, 因此修改源列表的内容后, 新的列表的内容也会被修改, 无法实现写操作的独立. 浅拷贝就是完全把源列表的第一层内存地址完全复制给新的变量名
对于不可变类型可以实现写操作独立, 但是对于可变类型, 无法实现写操作独立
默认情况下, 所有的copy的都是浅拷贝
图片.png
2.2.2 深copy
区分可变类型和不可变类型的copy机制, 要借助copy模块
import copy
list1=[
'dave',
'IT',
[11,22]
]
list3=copy.deepcopy(list1)
print(id(list1)) >> 1744448240576 # 拷贝一定是得到一个新列表, 内存地址不同
print(id(list3)) >> 1744448240832
print(list3) >> ['dave', 'IT', [11, 22]]
# 不可变 不可变 可变
print(id(list1[0]),id(list1[1]),id(list1[2]))
print(id(list3[0]),id(list3[1]),id(list3[2]))
>>
2646033824048 2646033824368 2646035904192
2646033824048 2646033824368 2646035835328
对于不可变类型, 和浅copy一样, 深拷贝是原封不动复制一份给新的列表, 内存地址是不变的, 这样读数据的时候还是读原先的内存地址, 节省空间
但是对于可变类型, 深拷贝会产生一个新的内存空间, 里面放原有的值, 然后绑定给新的列表
此时, 修改列表中的不可变类型, 那么不会影响新的列表, 这和浅copy一样
如果修改列表中的可变类型, 那么也不会影响新的列表, 这就实现了列表复制后的写操作
list1[0] = 'DAVE'
list1[1] = 'it'
list1[2][0] = 33
list1[2][1] = 44
print(list1) >> ['DAVE', 'it', [33, 44]] # list1完成修改
print(list3) >> ['dave', 'IT', [11, 22]] # list3并没有受影响
图片.png
结论:
如果需要复制出来一个新的列表, 并且实现两个列表写操作独立, 要用深copy