测开之数据类型进阶篇・第四篇《生成器和迭代器》
Posted 七月的小尾巴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了测开之数据类型进阶篇・第四篇《生成器和迭代器》相关的知识,希望对你有一定的参考价值。
生成器表达式
生成器的定义
在Python中,一边循环一边计算的机制,称为生成器:generator。
为什么要有生成器
列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。
创建生成器
tu = (i for i in range(10))
print(tu)
我们来看一下打印结果
<generator object <genexpr> at 0x1083fc410>
Process finished with exit code 0
从上方我们可以看到,他返回了一个生成器的对象。由此可见,如果我们用()的形式,生成的是一个生成器表达式。
那么什么是生成器表达式呢?这个相当于我们一次性将所有的数据都存入到生成器中,在我们需要用的时候,就会取一次数据。如上方我们生成了0-9的数字,那么我们需要如何获取这些数据呢?
上方我们有说,生成器是在我们使用的时候,就会取一次数据,所以python提供了一个内置的函数 next()
。
上方数据我们可以看到,每次我们调用next()
函数时,都会从生成器中获取一次数据。那么我们思考,当我们一直执行 next()
函数直到生成器中没有数据了,程序中会怎么处理呢?
下面我们来看一下:
从上图可以看出,当生成器中没有数据的时候,程序就会抛异常提示没有数据了。
生成器的工作原理
- 生成器(generator)能够迭代的关键是它有一个next()方法,工作原理就是通过重复调用next()方法,直到捕获一个异常。
- 带有 yield 的函数不再是一个普通函数,而是一个生成器generator。可用next()调用生成器对象来取值。next 两种方式 t.next() | next(t)。可用for 循环获取返回值(每执行一次,取生成器里面一个值)基本上不会用next()来获取下一个返回值,而是直接使用for循环来迭代)。
- yield相当于 return 返回一个值,并且记住这个返回的位置,下次迭代时,代码从yield的下一条语句开始执行。
- .send() 和next()一样,都能让生成器继续往下走一步(下次遇到yield停),但send()能传一个值,这个值作为yield表达式整体的结果
迭代器
迭代器指的是迭代取值的工具,迭代是指一个重复的过程,每一次重复都是基于上一次结果而来迭代提供了一种通用的不依赖索引的迭代取值方式。
>>> list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it)) # 输出迭代器的下一个元素
1
>>> print (next(it))
2
>>>
迭代器对象可以使用常规for语句进行遍历:
#!/usr/bin/python3
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ")
结果:
1 2 3 4
可迭代对象
但凡内置有__iter__方法的对象,都称为可迭代对象,可迭代的对象:str,list,tuple,dict,set,文件对象
迭代器对象
- 既内置又__next__方法的对象,执行该方法可以不依赖索引取值
- 又内置有__iter__方法的对象,执行迭代器的__iter__方法得到的依然是迭代器本身
- 迭代器一定是可迭代对象,可迭代对象不一定是迭代器对象,文件对象本身就是一个迭代器对象
工作原理
- 先调用in后对象的__iter__方法,将其变成一个迭代器对象
- 调用next(迭代器),将得到的返回值赋值给变量名
- 循环往复直到next(迭代器)抛出异常,for会自动捕捉异常然后结束循环
可以从for的角度,分辨但凡可以被for循环取值的对象就是可迭代对象
迭代器的优缺点
迭代器优点:
1.提供了一种通用不依赖索引的迭代取值方式
2.同一时刻在内存中只存在一个值,更节省内存
迭代器缺点:
1.取值不如按照索引的方式灵活,不能取指定的某一个值,只能往后取,不能往前去
2.无法预测迭代器的长度
以上是关于测开之数据类型进阶篇・第四篇《生成器和迭代器》的主要内容,如果未能解决你的问题,请参考以下文章