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

    直接用于for循环的对象,叫做可迭代对象,如列表,字典等。

    可以被next()函数调用,并返回下一个值的对象称为迭代器(iterator)。(next()方法在python2.7中使用__next__()方法)。

    在调用next()方法时,如果迭代器没有值可以返回,就会引发一个StopIteration异常。

    定义迭代器时要有next()方法和__iter__方法:

    class Fib(object):
        def __init__(self):
            self.a = 0
            self.b = 1
        def __next__(self):  #注意2和3版本的区别
            self.a , self.b = self.b, self.a + self.b
            return  self.b
        def __iter__(self):
            return  self

    然后可以实例化类,直接调用__next__()方法:

    fibs = Fib()
    print(fibs.__next__())
    print(fibs.__next__())
    print(fibs.__next__())
    print(fibs.__next__())
    print(fibs.__next__())
    
    ============================
    1
    2
    3
    5
    8

    另外一种迭代方法:

    fibs = Fib()
    for f in fibs:
        if f >1000:
            print(f)
            break
    ==========结果==========
    1597

    一个实现了__iter__()方法的对象师可迭代的,一个实现了next方法的对象则是迭代器。

    内建函数iter可以从迭代对象中获得迭代器:

    it = iter(["a","b","d","t","l"])
    
    it.__next__()
    Out[2]: 'a'
    
    it.__next__()
    Out[3]: 'b'

    使用list方法可以显式的将迭代器转换为列表

    d = iter([4,5,6,7])
    
    ld = list(d)   #将迭代器转换为列表
    
    type(d)
    Out[20]: list_iterator
    
    type(ld)
    Out[21]: list
    
    ld
    Out[22]: [4, 5, 6, 7]


    生成器:

    包含yield语句的函数称为生成器。

    ll = [[1,2],[3,4],[5,6]]
    def print_list(list):
        for sublist in list:
            for i in sublist:
                yield i     ###
            print()
    for num in print_list(ll):
        print (num, end=" ")

    上述函数打印出列表中的每一个数值,注意标记使用的是yield而不是print。

    它的行为和普通函数最大的差别在于,它不会像return那样返回值。每次产生一个值,使用yield语句,函数就会被冻结:即函数停在那点等待被重新唤醒。

    函数被重新唤醒后就从停止点开始执行。

    ###python3中的换行打印

    https://www.cnblogs.com/hwd9654/p/5707920.html

    大家应该知道python中print之后是默认换行的,
    
    那如何我们不想换行,且不想讲输出内容用一个print函数输出时,就需要改变print默认换行的属性,
    
    方法如下:
    
    print('contents', end='!@#$%^&*')
    
    end就表示print将如何结束,默认为end="
    "(换行)
    
    栗子:
    
    print("祝各位身体健康")
    
    print("")
    
     
    
    print("祝各位身体健康", end=' ')
    
    print("")

    生成器的与列表推导式:

    l = [x if x%3==0 else 0 for x in range(10)]   ##B
    
    l
    Out[30]: [0, 0, 0, 3, 0, 0, 6, 0, 0, 9]
    
    l = (x if x%3 == 0 else 0 for x in range(10))   ##A
    
    l.__next__()
    Out[33]: 0
    
    l.__next__()
    Out[34]: 0
    
    l.__next__()
    Out[35]: 0
    
    l.__next__()
    Out[36]: 3
    
    l.__next__()
    Out[37]: 0
    
    l.__next__()
    Out[38]: 0
    
    l.__next__()
    Out[39]: 6

    把列表生成器中的中括号换成括号就变成了生成器!
    生成器是一个包含yield关键字的函数。当它被调用时,在函数体中的代码不会被执行,而会返回一个迭代器。

    每次请求一个值,就会执行生成器中的代码,直达遇到一个yield或者return语句,yield意味着应该生成一个值。return语句意味着生成器要停止执行。

    ““”“生成器由两部分组成:生成器函数和生成器迭代器。生成器函数使用语句定义的,包含yield部分,生成器迭代器是这个函数的返回部分。””

    生成器的方法:

    • 生成器可以调用send方法,给yield语句传递一个值。但是需要注意的是,生成器在使用send方法时,生成器必须已经调用,也就是必须已经运行过next()方法。
    def repeater(value):   #定义一个生成器
        while True:
            new = (yield value)
            if new is not None:
                value = new
                
    
    r = repeater(42)        #实例一个生成器对象
    
    r.__next__()            #首先调用,执行生成器
    Out[42]: 42
    
    r.send("I love LFY")    ##给生成器传入数值
    Out[43]: 'I love LFY'
    
    s = repeater(56)        #实例另一个生成器
    s.send("wxz")           #然后直接调用send方法,报错!
    Traceback (most recent call last):
    
      File "<ipython-input-46-52ebe91b67e9>", line 1, in <module>
        s.send("wxz")
    
    TypeError: can't send non-None value to a just-started generator   
  • 相关阅读:
    Cesium加载倾斜摄影数据
    CentOS7安装Docker
    Docker镜像下载
    c#验证密码强度
    配置阿里yum源
    ftpbat脚本
    powershell-ftpmove文件到本地
    Session Setup Request,NTLMSSP_AUTH, User:Dmainhostname$
    smblog
    树莓派显示器屏幕休眠
  • 原文地址:https://www.cnblogs.com/wxzhe/p/8916373.html
Copyright © 2011-2022 走看看