这个运算符应该是绝大多数人没见过
[:]=
要体会这个运算符的神奇之处在于,
这个赋值居然没有改变引用
例子
from contextlib import contextmanager
@contextmanager
def list_transaction(orig_list):
working = list(orig_list)
yield working
orig_list[:] = working
这是一个使用@contextmanager
装饰器的上下文管理器
-
yield
相当于__enter__
函数中的返回 -
yield
行后的相当于__exit__
函数中的
list_transaction
函数的作用是一个事务列表
:
当with块
中正常执行完(没有抛出异常), 才使用副本列表代替原来的列表
lst = [1, 2, 3]
with list_transaction(lst) as working:
working.append(-1)
猜测 [:]=
的运作
可切片对象
[:]=
可迭代对象
>>> l
['a', 'b', 'c']
>>> l[:2]
['a', 'b']
>>> l[:2] = 'ddd'
>>> l
['d', 'd', 'd', 'c']
用 'ddd' 替换列表的前两个对象
>>> l[1:3] = [1,2,3,4]
>>> l
['d', 1, 2, 3, 4, 'c']
在中间操作
如果还设置步长的话, 那就是 一个萝卜一个坑
>>> l[1:5:2] = 'xyz'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: attempt to assign sequence of size 3 to extended slice of size 2
>>> l[1:5:2] = 'xy'
>>> l
['a', 'x', 2, 'y', 4, 'd', 'e', 'd', 'c']
并且, 这样的运算, 全程id(l)
都是不变的
即该列表的内存地址
没有变化过
类似直接根据对象的引用进行操作
(item)
()
(iterable)
再介绍一个海象运算符
:=
my_list = [1,2,3]
count = len(my_list)
if count > 3:
print(f"Error, {count} is too many items")
# 当转换为海象运算符时...
if (count := len(my_list)) > 3:
print(f"Error, {count} is too many items")