python -迭代器和生成器

可迭代对象

如何判断一个对象是不是可迭代对象:
方法一:isinstance(obj, Iterable)
方法二:看有没有__iter__方法

迭代器

如何判断某个对象是不是迭代器:
方法一:ininstance(obj, Iterator)
方法二:看对象有没有__iter__属性和__next__属性。
迭代器协议:

  1. 迭代器类型必须实现__iter__和__next__(python 2是next)
  2. __iter__方法必须返回self
  3. __next__必须返回下一个值,如果没有下一个则抛出StopIterator异常
  4. 对迭代器进行for操作时,每次操作都会执行__next__方法
  5. 只能迭代一遍。
  6. for语句的迭代,会忽略StopIteration异常。
from typing import Iterator

obj = range(1,2)
obj1 = iter(range(1,2)) #把range(1,2)转化为Iterator类型

for attr in dir(obj1):
	 print(attr)  #包含__iter__属性和__next__属性
 
print(isinstance(obj,Iterator))  # False
print(isinstance(obj1,Iterator)) #True

自己动手实现一个迭代器

# range(1,5)  1,2,3,4,5
# next(5) 1,2,3,4
class Next(object):
	def __init__(self, stop, start=0):
		self.start = 0
		self.stop = stop
		
	def __next__(self):
		"""如果有下一个数则返回下一个参数,如果没有下一个则抛出StopIteration异常"""
		if self.start >= self.stop -1:
			raise StopIteration
		self.start +=1
		return self.start
	
	def __iter__(self):
		return self

if __name__=='__main__':
	obj = Next(5)
	for i,value in enumerate(obj): # 将索引和值都迭代出来
		print(i, value) 
	for i in obj:
		print(i)
	# print(obj.__next__())		
	# print(obj.__next__())	
	# print(obj.__next__())	
	# print(obj.__next__())	
	# print(obj.__next__())	

迭代器的应用场景

  1. list存1~10000的数据,占10000个整数的内存,而迭代器,占用几个整数的内存。
  2. 用Python批量下载图片的爬虫,把所有图片都放到list中,占用内存;每获得一个图片,保存一个图片。
    类似装水,要把一桶水用杯子转移到另一个水桶中,
    list:50个杯子一次装50杯倒进另一个水桶里。
    迭代器:一个杯子,装50次依次倒入另一个水桶。

生成器

生成器的意义:为了快速方便地创建一个迭代器。
yield关键字,实现快速创建迭代器
yield在函数中用
如果一个函数中有yield关键字,调用函数的时候不会执行函数的内容,会返回一个对象,这个对象的类型是生成器类。
生成器一定是一个迭代器。
生成器是如何执行的?
yield和return的区别?
共同点:都是Python关键字
不同点:return是结束函数并返回值,yield是暂时离开函数,遇到__next__以后还会回到函数。
当要访问生成器的__next__方法时,函数会变成running状态,当执行完yield时会暂时离开函数,函数变成非running(挂起)。只有再次执行生成器__next__方法时,函数才会被唤醒。
什么时候会执行生成器对象的__next__方法呢?获取生成器下一个值的时候。

自己动手实现生成器

# 手动实现平方,传参(1,3),返回1,4,9
# 常规方法
result = []
for i in [1,2,3]:
	result.append(i*i)
print(result)

# 迭代器实现
class Squares(object):
	def __init__(self, start, stop):
		self.start = start
		self.stop = stop
		
	def __iter__(self):
		return self
		
	def __next__(self):
		if self.start >=self.stop+1:
			raise StopIteration
		current = self.start * self.start
		self.start +=1
		return current
# 生成器实现
def  squares(start, stop):
	for i in range(start, stop + 1):
		yield i * i
# 生成器表达式实现:⽣生成器表达式和列表推导式的语法基本上是⼀样的. 只是把[]替换成() 
squares2 = (i * i for i in range(1, 4))
	 
if __name__ == '__main__':
	# iterator = Squares(1,3)
	iterator = squares(1,3)
	for i, value in enumerate(iterator):
		print(i, value)
	


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值