python引用拷贝、生成器迭代器

引用VS拷贝

赋值操作总是储存对象的引用,而不是对象的拷贝。赋值操作会产生相同对象的多个引用,在原处修改可变对象时,可能会影响程序中其他地方对相同对象的其他引用。

拷贝方法:
  • L[:]复制序列
  • 字典copy方法(X.copy())复制字典
  • 内置函数(如list)生成拷贝(list(L))
  • copy标准库模块生成完整拷贝
    **注意:**无条件值的分片以及字典copy方法只能做顶层复制,不能复制嵌套的数据结构。使用标准的copy模块,copy.deepcopy(Y)对任意嵌套对象Y做完整的复制

并行遍历:zip和map

内置zip函数让我们使用for循环来并行使用多个序列,在基本运算中,zip会取得一个或多个序列为参数,然后返回元组列表,将这些序列中的并排的元素配成对。

L1 = [1,2,3,4]
L2 = [5,6,7,8]
zip(L1,L2)#object
list(zip(L1,L2))#[(1,5),(2,6),(3,7),(4,8)]
for (x,y) in zip(L1,L2):
	print(x,y,'--',x+y)

当参数长度不同时,zip会以最短序列的长度为准来截断所得到的元组。
和zip一样,map是python3.0中的一个值生成器,因此必须传递给list以一次性收集其结果)

list(map(ord,'spam'))#[115,112,97,109]
#对键赋值来创建字典
list(zip(keys,vals)#[('spam',1),('eggs',3),('toast',5)]

enumerate根据相对位置来配对可迭代对象中的项,filter选择一个函数为真的项reduce针对可迭代对象中的成对的项运行一个函数。

列表解析

列表解析在一个序列的值上应用一个任意表达式,将其结果收集到一个新的列表中并返回,从语法上来说,列表解析由方括号封装起来【提醒构造列表】,其形式是在方括号中编写一个表达式,其中的变量,在后面跟着的像一个for循环的头部一样的语句,python将这个表达式的应用循环中每次迭代的结果收集起来。

res = [ord(x) for x in 'spam']
[x ** 2 for x in range(10)]	

[x for x in range(5) if x%2 == 0]
list(filter((lambda x: x%2 ==0),range(5)))
res = []
for x in range(5):
	if x % 2 == 0:
		res.append[x]

还可以在列表解析中编写任意数量的嵌套for循环

res = [x+y for x in [0, 1, 2] for y in [100, 200, 300]]
[(x,y) for x in range(5) if x%2 ==0 for y in range(5) if y%2 ==1] #if分句过滤每个序列中需要迭代的元素

重访迭代器:生成器

延迟结果创建,需要时才产生结果,而不是立即产生结果

  • 生成器函数:编写为常规的def语句,但是使用yield语句一次返回一个结果,在每个结果之间挂起和继续它们的状态
  • 生成器表达式类似于列表解析,但返回按需产生结果的一个对象,而不是立即产生结果
    不会一次性构造一个列表,节省了内存空间,且允许计算时间分散到各个请求
生成器函数:yield return
状态挂起

生成器函数自动在生成值的时刻挂起并继续函数的执行。由于生成器函数在挂起时保存的状态包含它们的整个本地作用域,当函数恢复时,其本地变了保持了信息并使其可用。
生成器yields一个值,而不是返回一个值,yield语句挂起该函数并向调用者发送回一个值,但是保留足够的状态使函数能够从它离开的地方继续。

扩展生成器函数协议:next

send必须直接作为生成器对象的方法来调用,这些额外的方法只是在内置的生成器对象上实现,而__next__方法应用于所有的可叠戴对象(包括内置类型和用户定义的类)

生成器表达式:迭代器+列表解析

从语法上来讲,生成器表达式就像一般的列表解析一样,但是它们是括在圆括号中而不是方括号中的;从执行过程上来讲,生成器表达式不实在内存中构建结果,而是返回一个生成器对象,这个对象将会支持迭代协议并在任意的迭代语境的操作中。
一般不会机械得使用next迭代器来操作生成器表达式,for循环会自动触发

for num in(x**2 for x in range(4)):
	print('%s',num)

生成器表达式大体上可以认为是对内存空间的优化,不需要像列表解析一样,一次构造出整体结果列表。在实际中运行起来可能稍慢,对可能只对于非常大的结果集合的运算来说是最优的选择

生成器函数VS生成器表达式

G = (c * 4 for c in 'SPAM')	#表达式 
list(G)
def timesfour(S):	#函数
	for c in S:
		yield c * 4
G = timesfour('SPAM')
list(G)

生成器是单迭代器对象,只支持一次活跃迭代【不像一些内置类型】

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值