美文网首页
生成器-generator、迭代器-Iterator

生成器-generator、迭代器-Iterator

作者: 小飞船1号 | 来源:发表于2020-11-20 17:15 被阅读0次

生成器(generator)

定义
  • 通过列表生成式,我们可以直接创建一个列表。但受到内存限制,容量肯定是有限。(创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费。)
  • 所以如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。
  • 在Python中,这种一边循环一边计算的机制,称为生成器:generator。
要创建一个generator
1 只要把一个列表生成式的[]改成(),就创建了一个generator
  • 一个一个打印出来,可以通过next()函数获得generator的下一个返回值
    generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
  • 正确的方法是使用for循环,因为generator也是可迭代对象:
g = (x * x for x in range(4))
print(g)
#<generator object <genexpr> at 0x0000014E15F44E60>
print(next(g))
#0
print(next(g))
#1
#接着上边执行
for n in g:
    print(n)
#4
#9
for n in (x * x for x in range(2)):
    print(n)
#0
#1
2 函数定义中包含yield关键字那么这个函数就不再是一个普通函数,而是一个generator:

普通函数和generator函数不同之处

  • 普通函数和generator函数的执行流程不一样。
    普通函数是顺序执行,遇到return语句或者最后一行函数语句就返回。
    generator函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
  • 普通函数和generator函数调用结果不一样
    普通函数调用直接返回具体结果
    generator函数的“调用”实际返回一个generator对象<generator.......
def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)
o = odd()
print(next(o))
print(next(o))
for p in odd():
    print(p)
'''
step 1
1
step 1
1
step 2
3
step 3
5
'''
#-------------------------------------------------------------------------------------------------------------------------------
def start_requests():
    for p in range(1,5):
        url = f"https://seekingalpha.com/latest-articles?page={p}"
        yield {"url": url}   


g=start_requests()
print(next(g))
print(next(g))
print(next(g))
for p in start_requests():
    print(p)

'''
{'url': 'https://seekingalpha.com/latest-articles?page=1'}
{'url': 'https://seekingalpha.com/latest-articles?page=2'}
{'url': 'https://seekingalpha.com/latest-articles?page=3'}
{'url': 'https://seekingalpha.com/latest-articles?page=1'}
{'url': 'https://seekingalpha.com/latest-articles?page=2'}
{'url': 'https://seekingalpha.com/latest-articles?page=3'}
{'url': 'https://seekingalpha.com/latest-articles?page=4'}
'''

迭代器(Iterator)

可以直接作用于for循环的数据类型有以下几种:

  • 一类是集合数据类型,如list、tuple、dict、set、str等;
  • 一类是generator,包括生成器和带yield的generator function。
定义
  • Iterable可迭代对象:这些可以直接作用于for循环的对象统称为可迭代对象
  • Iterator迭代器:不但可以作用于for循环,还可以被next()函数调用并不断返回下一个值的对象称为迭代器
  • 凡是可作用于for循环的对象都是Iterable类型;
  • 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
  • 集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
    因为Python的Iterator对象表示的是一个数据流
    Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。
    可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度
    只不断通过next()实现按需计算下一个数据,所以Iterator计算是惰性,只在需要返回下一个数据时才会计算
    Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
from collections.abc import Iterator

a=isinstance((x for x in range(10)), Iterator)
print(a)
#True
b=isinstance(iter('abc'), Iterator)
print(b)
#True

相关文章

网友评论

      本文标题:生成器-generator、迭代器-Iterator

      本文链接:https://www.haomeiwen.com/subject/rcvdiktx.html