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

    可迭代:在Python中如果一个对象有__iter__( )方法,则称这个对象是可迭代的(Iterable);

        其中__iter__( )方法的作用是让对象可以用for ... in循环遍历,列表List、元组Tuple、字典Dictionary、字符串String等数据类型都是可迭代的

    迭代器:在Python中如果一个对象有__iter__( )方法和__next__( )方法,则称这个对象是迭代器(Iterator);其中__iter__( )方法是让对象可以用for ... in循环遍历,__next__( )方法是让对象可以通过next(实例名)访问下一个元素。注意:这两个方法必须同时具备,才能称之为迭代器。列表List、元组Tuple、字典Dictionary、字符串String等数据类型虽然是可迭代的,但都不是迭代器,因为他们都没有next( )方法。

     1 a = [1,2,3,4]
     2 a.__iter__()
     3 #列表是可迭代得
     4 lst_iterator = a.__iter__()
     5 # lst_iterator.__iter__()
     6 #lst_iterator就是一个迭代器。
     7 print(lst_iterator.__next__())
     8 #执行__next__方法可以遍历里面的数字
     9 from collections import Iterator
    10 from collections import Iterable
    11 print(isinstance(lst_iterator,Iterator))
    12 #判断是否是迭代器
    13 print(isinstance(a ,Iterable))
    14 #判断是否是可迭代的
    View Code

    备注:如果迭代器里面的数据遍历完成之后会报错。:stopIteration

    异常处理:try,except 可以解决这种问题

    1 #异常处理,遍历完成之后会报错,可以用异常处理来解决
    2 lis = [1,2,3].__iter__()
    3 while True:
    4     try:
    5         print(lis.__next__())
    6     except StopIteration:
    7         #StopIteration ,报错信息。如果提示这个,则直接break
    8         break
    View Code

    迭代器的优点:

    1、能够对python 中的基本数据类型进行统一的遍历,不需要关心每个值是什么。【例如:字典,你必须知道要他们key才可以取值】

    2、它可以节省内存

    例如: f = open('file','w')文件句柄就是个天生迭代器 ;range(100) 是个可迭代对象。用.__iter__ 可以把他变成一个迭代器

    生成器  (Gerator),Iterator(迭代器):生成器就是迭代器,生成器是自己写出来的

     1 def generator_func():
     2     print('123')
     3     yield  1111
     4 g = generator_func()#---生成器的本质就是迭代器
     5 print(g)
     6 ret = g.__next__()
     7 print(ret)
     8 #带yield关键字的函数就是生成器函数
     9 #生成器函数在执行的时候返回一个生成器
    10 #输出:<generator object generator_func at 0x000002897D1F1B88>
    11 #123
    12 #1111
    View Code
    # 错误示范:不能这么操作g = generator_func().__next__()
    # 生成器可以强转成列表等 例:list(g)

    迭代器是可迭代对象。迭代器 = 可迭代对象.___iter__()

    从生成器里取值:

      1、__inter__ 有几个yield就可以取几次

      2、for 喜欢取值

      3、注意:再调用生成器函数的时候,要先获取生成器,再进行next 取值

      4、其他数据类型进行强转,里面装的是生成器所有的值

      5、生成器中的内容只能取一次,按顺序取值,去完为止

      6、生成器中的yield一般都有2个以上。如果一个,就相当于return .

      7、 yield 一般都是和循环一起使用

    例:取衣服,用上循环。

    1 def get_clothing():
    2     for cloth in range(100):
    3         yield  ' 第%s件衣服'%cloth
    4 generate = get_clothing()
    5 print(next(generate))#==generate.__next__()
    6 print(next(generate))
    7 print(next(generate))
    8 for i in range(50):#一次性取50件衣服
    9     print(generate.__next__())
    # for i in get_clothing():
       if i == '第100件衣服':
          break

     send命令:

     1 def func():
     2     value = yield 1
     3     yield value
     4 g = func()
     5 print(g.__next__())# 生成器的第一步只能先用next。
     6 print(g.send(10))#到yield位置后,如果有赋值 = 才可以用
     7 #send命令,不然就算send也没用!
     8 #这里send是赋值给value
     9 #send 不仅next的功能,也可以传进去值(赋值操作)
    10 #yield 是返回值
    备注:如果send 要多次传值必须要有一个未被返回的yield。
    如果value没有接收的值的话,会返回None

    1、如果第一个yield 只是为了激活生成器。可以写个装饰器(生成器预激装饰器)

    1 def wrapper(func):
    2     def inner(*args,**kwargs):
    3         ret = func(*args,**kwargs)
    4         ret.__next__()
    5         return ret
    6     return inner
    7 @wrapper

     面试题:查看输出结果

    例1

     1 def demo():
     2     for i in range(4):
     3         yield i
     4 g = demo()
     5 g1 = (i for i in g)
     6 g2 = (i for i in g1)
     7 print(list(g1))# g1里面的值已经被list获取,所有g2是个空列表
     8 print(list(g2))
     9 #[0,1,2,3]
    10 #[]

    例2 注意:生成器在调用的时候才生效。下面这道题,就是当N = 10 就一直是10,而不是1, 

     1 def add(n,i):
     2     return n + i
     3 def test():
     4     for i in range(4):
     5         yield i
     6 g = test()#生成器
     7 for n in [1,10]:
     8     g = (add(n,i) for i in g)
     9 # 相当于
    10 #n =1
    11 #g = (add(n,i) for i in test())n
    12 #n =10
    13 #g = (add(n,i) for i in add(1,i) for i in test())
    14 print(list(g))
    15 #此时N =10
    16 #g = (add(n,i) for i in add(10,i) for i in [0,1,2,3])
    17 #10+0,10+1,10+2,10+3
    18 #g = (add(n,i) for i in 10,11,12,13)
    19 #10+10,10+11,10+12,10+13
    20 #输出 [20, 21, 22, 23]
  • 相关阅读:
    PortalBasic Java Web 应用开发框架:应用篇(八) —— 整合 Freemarker
    PortalBasic Java Web 应用开发框架:应用篇(七) —— 页面静态化
    用 Java 实现的日志切割清理工具(源代码下载)
    PortalBasic Java Web 应用开发框架:应用篇(十) —— 新 DAO 访问接口
    PortalBasic Java Web 应用开发框架:应用篇(九) —— 多入口 Action
    PortalBasic Java Web 应用开发框架 v2.6.1(源码、示例及文档)
    RealThinClient LinkedObjects Demo解析
    windows server 2003 可以通过IP访问网络,而无法打开网页
    IIS 指定了身份验证方案“IntegratedWindowsAuthentication, Anonymous”,但绑定仅支持一种身份验证的规范。有效的身份验证方案为摘要、协商、NTLM、基本或匿名。解决方法
    C# 事务
  • 原文地址:https://www.cnblogs.com/sunjinchao/p/10915282.html
Copyright © 2011-2022 走看看