zoukankan      html  css  js  c++  java
  • day15笔记

    一、迭代器

    迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

    1. 可迭代对象

    以直接作用于 for 循环的数据类型有以下几种:
      一类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等;
      一类是 generator ,包括生成器和带 yield 的generator function。
    这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 。

    2. 判断是否可以迭代

    可以使用 isinstance() 判断一个对象是否是 Iterable 对象:

    In [50]: from collections import Iterable
    
    In [51]: isinstance([], Iterable)
    Out[51]: True
    
    In [52]: isinstance({}, Iterable)
    Out[52]: True
    
    In [53]: isinstance('abc', Iterable)
    Out[53]: True
    
    In [54]: isinstance((x for x in range(10)), Iterable)
    Out[54]: True
    
    In [55]: isinstance(100, Iterable)
    Out[55]: False

    3.迭代器

    可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

    可以使用 isinstance() 判断一个对象是否是 Iterator 对象:

    In [56]: from collections import Iterator
    
    In [57]: isinstance((x for x in range(10)), Iterator)
    Out[57]: True
    
    In [58]: isinstance([], Iterator)
    Out[58]: False
    
    In [59]: isinstance({}, Iterator)
    Out[59]: False
    
    In [60]: isinstance('abc', Iterator)
    Out[60]: False
    
    In [61]: isinstance(100, Iterator)
    Out[61]: False

    4.iter()函数

    生成器都是 Iterator 对象,但 list 、 dict 、 str 虽然是 Iterable ,却不是 Iterator 。

    把 list 、 dict 、 str 等 Iterable 变成 Iterator 可以使用 iter() 函数:

    In [62]: isinstance(iter([]), Iterator)
    Out[62]: True
    
    In [63]: isinstance(iter('abc'), Iterator)
    Out[63]: True

    迭代器一定是可迭代对象,但是可迭代对象不一定是迭代器。
    list,truple,str这些都是可迭代对象,但是他们不一定是迭代器。迭代器本身不知道自己要执行多少次,所以可以理解为不知道有多少个元素,每调用一次next(),就会往下走一步,是惰性的。
    迭代器提供了一种不依赖索引取值的方式,这样可以遍历没有索引的可迭代对象,比如字典、集合、文件等等,加载这一个元素至内存中随后释放,相比之下相当节省内存,这也是迭代器最大的优点,但是我们没有办法获取迭代器的长度,而且只能往后依次取值。
    迭代是数据处理的基石。当内存中放不下数据集时,我们要找到一种惰性获取数据的方式,即按需一次获取一个数据项,这就是迭代器模式。

    总结

    凡是可作用于 for 循环的对象都是 Iterable 类型;
    凡是可作用于 next() 函数的对象都是 Iterator 类型
    集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不过可以通过 iter() 函数获得一个 Iterator 对象。

    二、生成器

    生成器是一个带 yield 语句的函数。一个函数或者子 程序只返回一次,但一个生成器能暂停执行并返回一个中间的结果,返 回一个值给调用者并暂停执行。当生成器的 next()方法被调用的时候,它会准确地从离开地方继续

    下面看示例:

    1 def func():
     2     print('11111111')
     3     yield [1]
     4     print(2222222222)
     5     yield 2
     6     print(3333333333)
     7     yield 3
     8 
     9 ret=func()
    10 r1=ret.__next__()
    11 print(r1)
    12 r2=ret.__next__()
    13 print(r2)
    14 r3=ret.__next__()
    15 print(r3)

    结果为:

    1 11111111
    2 13 2222222222
    4 2
    5 3333333333
    6 3

    由于 python 的 for 循环有 next()调用和对 StopIteration 的处理, 使用一个 for 循环而不是手 动迭代穿过一个生成器(或者那种事物的迭代器)总是要简洁漂亮得多。例:

     1 def func():
     2     print('11111111')
     3     yield [1]
     4     print(2222222222)
     5     yield 2
     6     print(3333333333)
     7     yield 3
     8 ret=func()
     9 for i in ret:
    10     print(i)

    结果同前面相同。

    这些简单的例子应该让你有点明白生成器是如何工作的。除了 next()来获得下个生成的值,用户 可以将值回送给生成器[send()],在生成器中抛出异常,以及要求生成器退出[close()]

    下面是一个展示了这些特性的,简单的例子。

    1 def counter(start_at=0):
    2   count = start_at
    3   while True:
    4     val = (yield count) if val is not None:
    5     count = val
    6   else:
    7     count += 1

    生成器带有一个初始化的值,对每次对生成器[next()]调用以 1 累加计数。用户已可以选择重 置这个值,如果他们非常想要用新的值来调用 send()不是调用 next()。这个生成器是永远运行的,所以如果你想要终结它,调用 close()方法。如果我们交互的运行这段代码,会得到如下输出:

    1 >>> count = counter(5)
     2 >>> count.next()
     3 5
     4 >>> count.next()
     5 6
     6 >>> count.send(9)
     7 9
     8 >>> count.next()
     9 10
    10 >>> count.close()
    11 >>> count.next()
    12 Traceback (most recent call last):
    13 File "<stdin>", line 1, in <module>
    14 StopIteration

     三、 for循环的工作原理

    dic = {"name": "egon", 'age': 18, 'gender': "male"}
    
    dic_iterator = dic.__iter__()
    while True:
        try:
            res = dic_iterator.__next__()
            print(res)
        except StopIteration:
            break
    
    for k in dic:
        print(k)
    步骤1 dic_iterator = dic.__iter__()
    步骤2 k=dic_iterator.__next__(),执行循环体代码
    步骤3 循环往复,直到抛出异常,for循环会帮我们捕捉异常结束循环
  • 相关阅读:
    Kettle 使用入门
    git mac客户端使用提交与同步
    MAC 远程桌面链接 证书或链接无效
    mac下wifi无法连接的问题
    mysql时间段内查询
    mybatis 特殊符号及like的使用
    mac下剪切文件或文件夹
    eclipse下使用git下载和上传项目
    unbutu下搭建FTP服务
    mybatis 的if else
  • 原文地址:https://www.cnblogs.com/panwenbin-logs/p/13363777.html
Copyright © 2011-2022 走看看