week3 day3迭代器和生成器

week3 day3迭代器和生成器

    • 一. 迭代器
    • 1.1 什么是迭代器?
    • 1.2 为何要使用迭代器?
    • 1.3 如何使用迭代器?
    • 1.4 迭代器例子
    • 二. 生成器
    • 2.1 什么是生成器?
    • 2.2 为何要用生成器?
    • 2.3 怎么使用生成器?

一. 迭代器

我们之前在学习流程控制的时候学习过for循环,那么for循环的内在工作原理是什么呢?今天,我们将先来探讨for循环的工作原理。

我们所学习的数据类型中,有很多数据类型都有内置的__iter__方法。

''.__iter__()
[].__iter__()
().__iter__()
{
     }.__iter__()
{
     }.__iter__()
f=open(r'a.txt',mode='rb')
f.__iter__()
f.__next__()

我们发现字符串,列表,元组,字典,集合文件都有python解释器内置的iter方法,而文件不止有iter方法,还有next方法。

1.1 什么是迭代器?

迭代器:迭代取值的工具。
什么是迭代:迭代的基础是重复,但是每次重复都是在上一次基础上进行的。

1.2 为何要使用迭代器?

  1. 迭代器提供了一种不依赖于索引的通用的可以取值的方法。
  2. 节省内存。

1.3 如何使用迭代器?

可迭代对象:含有__iter__方法的对象。

当可迭代对象调用__iter__方法的时候,返回一个迭代器对象。

迭代器对象:含有__iter__和__next__方法的对象。

当迭代器对象调用__iter__方法的时候,返回的是它自己。
当迭代器对象调用__next__方法的时候,拿到的是下一个值。
可以一直使用__next__方法取下一个值,直到抛出异常StopIteration。

1.4 迭代器例子

nums=[11,22,33,44,55]
nums_iter=nums.__iter__() or nums_iter=iter(nums) # 拿到迭代器对象
print(nums_iter.__next__()) / print(next(nums_iter))----->11
print(nums_iter.__next__()) / print(next(nums_iter))----->22
print(nums_iter.__next__()) / print(next(nums_iter))----->33
print(nums_iter.__next__()) / print(next(nums_iter))----->44
print(nums_iter.__next__()) / print(next(nums_iter))----->55
print(nums_iter.__next__()) / print(next(nums_iter))----->StopIteration
补充一个报错检测机制:
while True:
	try:
		print(nums_iter.__next__())
	except:
		StopIteration
		break

二. 生成器

迭代器的有一个优点是节约内存,但现在我们进行的操作一直是将某个已经占据了内存的数据转换成迭代器对象,然后遍历取值,但是如何才能发挥迭代器节约内存的优点呢?如果我们可以自定义迭代器,那么是不是就可以节约内存呢?

2.1 什么是生成器?

生成器就是自定义的迭代器。

2.2 为何要用生成器?

可以自定义迭代的范围,节省内存。

2.3 怎么使用生成器?

我们之前学过return,return可以让我们拿到函数的返回值,但是同时,函数体遇到return将终止后续代码的运行。因此,需要一个可以拿到返回值,但不会终止函数运行的东西,这就是yield。

def func():
	print(111)
	yield 1
	print(222)
	yield 2
	print(333)
	yield 3
func()----->

当函数中出现yield时,因为yield的存在,调用函数不会直接运行函数。但是我们前面说过yield是可以返回值的,因此,我们打印一下func的返回值看一下:

res=func()
print(res)-----><generator object func at 0x00000231C367C5C8>

我们发现虽然函数体没有运行,但我们得到了一个生成器,我们之前说过生成器就是一个自定义的迭代器,那么迭代器的内置方法生成器一定都有!

func_iter=iter(func())
res1=next(func_iter)----->111 # res1拿到的是第一个yield的值
print(res1)----->1
res2=next(func_iter)----->222 # res2拿到的是第二个yield的值
print(res2)----->2
res3=next(func_iter)----->333 # res3拿到的是第三个yield的值
print(res3)----->3

你可能感兴趣的:(python学习,python)