zoukankan      html  css  js  c++  java
  • 迭代器与生成器

    一.迭代和可迭代协议

      迭代:简单来说,就是可以将数据集内的数据一个挨一个取出来

      可以被迭代要满足的要求就是可迭代协议,要想可迭代,内部必需有一个_iter_方法

    二.迭代器

      迭代器遵循协议:必须有_iter_、_next_方法

      迭代器的_next_方法(不依赖for循环实现遍历)

     1 l = [1,2,3,4]
     2 l_iter = l.__iter__()
     3 item = l_iter.__next__()
     4 print(item)
     5 item = l_iter.__next__()
     6 print(item)
     7 item = l_iter.__next__()
     8 print(item)
     9 item = l_iter.__next__()
    10 print(item)
    11 item = l_iter.__next__()
    12 print(item)

      由于元素只有四个,所以迭代不到数据会报错(用异常处理机制解决)

    1 l = [1,2,3,4]
    2 l_iter = l.__iter__()
    3 while True:
    4     try:
    5         item = l_iter.__next__()
    6         print(item)
    7     except StopIteration:
    8         break

      range()  (可迭代的对象,但不是一个迭代器)

    三.生成器

      两种迭代器:

      一种是调用方法直接返回的,一种是可迭代对象通过执行_iter_方法,迭代器有个好处就是可以节省内存

      我们自己写的实现迭代器功能的东西就叫迭代器

      python中提供的生成器

      1.生成器函数:常规函数定义,但是使用的是yield返回语句而不是return语句返回的结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行。

      2.生成器表达式:类似于列表推导,但是生成器返回按需产生结果的一个对象,而不是一次产生一个结果列表

      生成器本质:迭代器,自带了iter和next方法,不用我们去实现

      特点:惰性运算,开发者自定义

    四.生成器函数

      一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。

     1 import time
     2 def genrator_fun1():
     3     a = 1
     4     print('现在定义了a变量')
     5     yield a
     6     b = 2
     7     print('现在又定义了b变量')
     8     yield b
     9 
    10 g1 = genrator_fun1()
    11 print('g1 : ',g1)       #打印g1可以发现g1就是一个生成器
    12 print('-'*20)   #我是华丽的分割线
    13 print(next(g1))
    14 time.sleep(1)   #sleep一秒看清执行过程
    15 print(next(g1))

      生成器监听文件输入的内容

     1 import time
     2 
     3 def tail(filename):
     4     f = open(filename)
     5     f.seek(0, 2) #从文件末尾算起
     6     while True:
     7         line = f.readline()  # 读取文件中新的文本行
     8         if not line:
     9             time.sleep(0.1)
    10             continue
    11         yield line
    12 
    13 tail_g = tail('tmp')
    14 for line in tail_g:
    15     print(line)

      计算移动平均值

     1 def averager():
     2     total = 0.0
     3     count = 0
     4     average = None
     5     while True:
     6         term = yield average
     7         total += term
     8         count += 1
     9         average = total/count
    10 
    11 
    12 g_avg = averager()
    13 next(g_avg)
    14 print(g_avg.send(10))
    15 print(g_avg.send(30))
    16 print(g_avg.send(5))
    17 

      预激协程装饰器

     1 def init(func):  #在调用被装饰生成器函数的时候首先用next激活生成器
     2     def inner(*args,**kwargs):
     3         g = func(*args,**kwargs)
     4         next(g)
     5         return g
     6     return inner
     7 
     8 @init
     9 def averager():
    10     total = 0.0
    11     count = 0
    12     average = None
    13     while True:
    14         term = yield average
    15         total += term
    16         count += 1
    17         average = total/count
    18 
    19 
    20 g_avg = averager()
    21 # next(g_avg)   在装饰器中执行了next方法
    22 print(g_avg.send(10))
    23 print(g_avg.send(30))
    24 print(g_avg.send(5))
    25 
    26 预激协程的装饰器

      yield from

     1 def gen1():
     2     for c in 'AB':
     3         yield c
     4     for i in range(3):
     5         yield i
     6 
     7 print(list(gen1()))
     8 
     9 def gen2():
    10     yield from 'AB'
    11     yield from range(3)
    12 
    13 print(list(gen2()))
    14 
    15 yield from

      总结:列表解析和生成器表达式相比,后者更节省内存

  • 相关阅读:
    关于idea中启动clean时Process terminated报错
    关于idea启动jsp时候Please, configure Web Facet first!
    关于Javaweb中jstl的foreach不能显示数据的问题
    关于Javaweb中报错信息Cause: java.sql.SQLException: Unknown initial character set index '255' received from server.解决办法
    关于使用idea 进行druid的数据库连接报错解决Cannot resolve com.mysq.jdbc.Connection.ping method. Will use 'SELECT 1' instead
    关于c3p0中显示数据库连接超时处理方法
    havel定理
    Skier
    扩展欧几里德算法(待补充)
    next_permutation(全排列)
  • 原文地址:https://www.cnblogs.com/sxh-myblogs/p/7274565.html
Copyright © 2011-2022 走看看