zoukankan      html  css  js  c++  java
  • 【python之路29】python生成器generator与迭代器

    补充:2020年3月1日

    一、迭代器--补充

    li = [11,22,33]
    bol = "__iter__" in dir(li)
    print(bol) #如果__iter__list功能里面表示li是可迭代的

    #li是可迭代的,但li不是迭代器
    it = li.__iter__()
    print(it) #<list_iterator object at 0x0000026F5CFFEA58>,则it是个迭代器
    #print(it.__next__()) #迭代器可以用it.__next__()一个一个的按顺序取值

    #迭代器的内部取值原理
    while True:
    try:
    print(it.__next__())
    except StopIteration:
    break

    #总结:可迭代的对象不一定是迭代器,例如list,单迭代器一定是可迭代的

     二、生成器---补充

    生成器,可以取迭代循环,实质上生成器是迭代器

    send(1) 的用法与__next__()用法基本一样,唯一的区别是,先发送一个值给上一个yield然后再向下执行:

    def func():
        print('11')
        aa = yield 1
        print(aa)
        print('22')
        bb = yield 2
        print(bb)
        print('33')
        yield 3
    
    
    gen = func()  # 运行后gen是生成器
    gen.__next__()
    gen.send("aa")
    gen.send("bb")
    # 运行结果:
    # 11
    # aa
    # 22
    # bb
    # 33

    一、python生成器

     python生成器原理:

    只要函数中存在yield,则函数就变为生成器函数

    #!usr/bin/env python
    # -*- coding:utf-8 -*-
    
    def xrange():
        print('11')
        yield 1
        print('22')
        yield 2
        print('33')
        yield 3
    
    r = xrange()  #不执行,产生一个生成器,注意xrange不是生成器,r才是生成器
    print(r)  #<generator object f1 at 0x0000017D4A1D1CA8>
    
    re = r.__next__()
    print(re) #打印输出11 1,生成器执行完yield后暂停执行,当再次执行__next__()时,从上一个yield后面继续执行
    re = r.__next__()
    print(re) #打印输出11 1
    re = r.__next__()
    print(re) #打印输出11 1

     python2.7中xrange的原理

    #!usr/bin/env python
    # -*- coding:utf-8 -*-
    def xxrange(n):
        num = 0
        while True:
            if num == 5:
                return
            yield num
            num += 1
    
    r = xxrange(5)
    re1 = r.__next__()
    re2 = r.__next__()
    re3 = r.__next__()
    re4 = r.__next__()
    re5 = r.__next__()
    print(re1,re2,re3,re4,re5)  #打印0 1 2 3 4

     2.7版本xrange完全实现:

    #!/ufr/bin/env python
    # -*- coding:utf-8 -*-
    
    def xxrange(n1,n2=None):
        if n2 is None:
            n = 0
            while n < n1:
                yield n
                n = n + 1
        else:
            n = n1
            while n1 <= n < n2:
                yield n
                n = n + 1
    
    
    #bb = xxrange(5)
    for i in xxrange(1,5):
        print(i)

    1、迭代器

    迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件

    特点:

    1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
    2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
    3. 访问到一半时不能往回退
    4. 便于循环比较大的数据集合,节省内存
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    >>> a = iter([1,2,3,4,5])
    >>> a
    <list_iterator object at 0x101402630>
    >>> a.__next__()
    1
    >>> a.__next__()
    2
    >>> a.__next__()
    3
    >>> a.__next__()
    4
    >>> a.__next__()
    5
    >>> a.__next__()
    Traceback (most recent call last):
      File "<stdin>", line 1in <module>
    StopIteration

    2、生成器

    一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);如果函数中包含yield语法,那这个函数就会变成生成器;

    1
    2
    3
    4
    5
    def func():
        yield 1
        yield 2
        yield 3
        yield 4

    上述代码中:func是函数称为生成器,当执行此函数func()时会得到一个迭代器。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >>> temp = func()
    >>> temp.__next__()
    1
    >>> temp.__next__()
    2
    >>> temp.__next__()
    3
    >>> temp.__next__()
    4
    >>> temp.__next__()
    Traceback (most recent call last):
      File "<stdin>", line 1in <module>
    StopIteration

    3、实例

    a、利用生成器自定义range

    1
    2
    3
    4
    5
    6
    7
    8
    def nrange(num):
        temp = -1
        while True:
            temp = temp + 1
            if temp >= num:
                return
            else:
                yield temp

    b、利用迭代器访问range

    1
    ...
  • 相关阅读:
    thinkphp3.2.3版本在windows本地apache环境运行正常,上传到centos服务器apache环境中出现:thinkphp 上传根目录不存在!请尝试手动创建:uploads/
    [POI2013]LUK-Triumphal arch
    【背包问题】
    2016 acm香港网络赛 A题. A+B Problem (FFT)
    tomcat部署项目的三种方式
    仿照ArrayList自己生成的MyList对象
    使用回调函数实现回文判断
    关于angularjs的model的一些问题
    关于使用Tomcat服务器出现413错误的解决办法(Request Entity Too Large)
    关于angularjs+typeahead的整合
  • 原文地址:https://www.cnblogs.com/sunshuhai/p/6496880.html
Copyright © 2011-2022 走看看