一:迭代器
1.创建迭代器 (就可以看成特殊的容器)
iter(序列类型)
2.通过next去获取迭代器中的元素,每次只能取一个,而且已经取过的元素就不能再获取到了
iter1 = iter({1:3, 'b':4})
print(iter1)
print(next(iter1))
# print(next(iter1))
print(iter1.__next__())
二:生成器和生成式:生成器就是创建迭代器的函数;生成式就是创建迭代器的表达式
a.生成式: (value for value in 序列)-->注意加括号
# list1 = [i for i in range(10)] 创建列表
iter2 = (i for i in range(10))
print(list1)
print(iter2)
print(iter2.__next__())
print(iter2.__next__())
print(iter2.__next__())
b.生成器:有关键字yield的函数就数生成器,函数的返回值就是一个迭代器(不管函数有没有返回值)
格式:yield 表达式
迭代器中的元素就是yield后面的值的集合
注意:
def func():
for i in range(10, 13):
yield i # 在函数执行的过程中,每次遇到yield就会将yield的值存到迭代器中
print('aaa')
return 10
func2 = func()
list1 = list(func2)
print(list1)
判断一个对象是否是可迭代对象:isinstance(对象,Iterable)
from collections import Iterable
isinstance([], Iterable)
# True
isinstance({}, Iterable)
# True
isinstance('abc', Iterable)
# True
isinstance((x for x in range(10)), Iterable)
# True
print(isinstance(100, Iterable))
# False
判断一个对象是否是迭代器:isinstance(对象,Iterator)
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
用iter()将Iterable变成Iterator
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
对yield的总结
(1):通常的for..in...循环中,in后面是一个数组,这个数组就是一个可迭代对象,类似的还有链表,字符串,文件。他可以是a = [1,2,3],也可以是a = [x*x for x in range(3)]。
它的缺点也很明显,就是所有数据都在内存里面,如果有海量的数据,将会非常耗内存。
(2)生成器是可以迭代的,但是只可以读取它一次。因为用的时候才生成,比如a = (x*x for x in range(3))。!!!!注意这里是小括号而不是方括号。
(3)生成器(generator)能够迭代的关键是他有next()方法,工作原理就是通过重复调用next()方法,直到捕获一个异常。
(4)带有yield的函数不再是一个普通的函数,而是一个生成器generator,可用于迭代
(5)yield是一个类似return 的关键字,迭代一次遇到yield的时候就返回yield后面或者右面的值。而且下一次迭代的时候,从上一次迭代遇到的yield后面的代码开始执行
(6)yield就是return返回的一个值,并且记住这个返回的位置。下一次迭代就从这个位置开始。
(7)带有yield的函数不仅仅是只用于for循环,而且可用于某个函数的参数,只要这个函数的参数也允许迭代参数。
(8)send()和next()的区别就在于send可传递参数给yield表达式,这时候传递的参数就会作为yield表达式的值,而yield的参数是返回给调用者的值,也就是说send可以强行修改上一个yield表达式值。
(9)send()和next()都有返回值,他们的返回值是当前迭代遇到的yield的时候,yield后面表达式的值,其实就是当前迭代yield后面的参数。
(10)第一次调用时候必须先next()或send(),否则会报错,send后之所以为None是因为这时候没有上一个yield,所以也可以认为next()等同于send(None)
网友评论