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

    迭代和递归,最初在DNS resolution中见到过,  迭代指的A问B ,A问C,A问D .   A向上一代一代的查问

    下面进入本次文章的主题

    python中的迭代和生成

    为什么引入迭代:

    迭代是数据处理的基石。扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,

    即按需一次获取一个数据项。这就是迭代器模式(Iterator pattern)。

    可迭代的判断:  1.用命令 isinstance([], Iterable)

                   2.  如果这个对象中有__next__()方法,这个对象就是可迭代对象

    注意: 字符串str,列表list,元组tuple,字典dic,集合set,文件对象 都不是可迭代对象.都没__next__方法

    在for循环,就是使用__iter__方法,将其变成了可迭代对象   

    list1 = [1,2,3,4]

    iter_l = l.__iter__()

    print(iter_l.__next__()

    //////////////生成器 generator

    生成器的作用: 自动实现了生成器协议,不用再调用 __iter__()方法 再去生成可迭代对象了.

    生成器 generator.创建方法: 一  二

    创建生成器法一 : 用 ()

    生成器也是可迭代对象,所以也能使用for循环啦

    g = (x*x for x in range(10))

    for a in  g:   (原理 调用的next方法,不断的去next

    print(a)

    创建生成器法二: 关键字 yield

    ·         yield 是一个类似 return 的关键字,只是这个函数返回的是个生成器

    ·         当你调用这个函数的时候,函数内部的代码不立刻执行 ,而是返回一个生成器对象

    ·         当使用for进行迭代的时候,函数中的代码才会执行

     

    def createGenerator():

        for i in range(3):

            yield i * i

    myGenerator = createGenerator()  #得到一个生成器对象

     

    for i in myGenerator:

        print(i)

     

    第二个例子(多理解):

    def foo():

        print("starting...")

        while True:

            res = yield 4

            print("res:",res)

     

    g = foo()

    return_val = next(g)

    print(return_val)

    print("*"*20)

    print(next(g))

     

    程序执行情况:

    starting...

    4

    ********************

    res: None

    4

    1.       g = foo()程序开始执行 : 因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)

    2. print(return_val)     调用next方法,foo函数开始执行,先执行foo函数中的print方法,然后进入while循环

    遇到yield关键字,然后把yield想象成return,return了一个4之后,程序停止,没有执行赋值给res操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面的print的结果,第二个是return出的结果)是执行print(next(g))的结果,

     

    4.程序执行print("*"*20),输出20*

     

    5.执行第二个print(next(g)),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行res的赋值操作,res = yield 这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候res赋值是None,所以接着下面的输出就是res:None,

     

    6.程序会继续在while里执行,又一次碰到yield,这个时候同样return 4,然后程序停止,print函数输出的4就是这次return出的4.

     

    关键问题  y = yield 8 怎么输出取决于send next

    The value of the yield expression after resuming depends on the method which resumed the execution. If __next__()  (or .next()) is used then the result is None. Otherwise, if send() is used, then the result will be the value passed in to that method.

     

    yield 继续加码  关于send

    send作用:1传值给yield    2.__next__()一样的功能

    def test():

        i = 1

        while i < 5:

            temp = yield i**2

            cc = 3

            print(temp)

            i += 1

     

    t = test()

    a = t.__next__()

    print(a)

     

    t.send('hello world')

    输出内容:

    1

    hello world  (这是 print(temp)的结果)

    分析:  1.执行yield i**2 返回给变量所以打印1

    2.    t.send('hello world'yield后面的值变成'hello world,  然后是第二个next, temp = 'hello world  ……..''

     

     

  • 相关阅读:
    面试笔试题
    类型转换
    c++11之智能指针
    c++预处理命令
    java的javac不能正常运行
    状态模式
    观察者模式Observer
    带图形界面的虚拟机安装+Hadoop
    测试工具的使用:JUnit、PICT、AllPairs
    Test_1 一元二次方程用例测试以及测试用例
  • 原文地址:https://www.cnblogs.com/zyhe/p/10549267.html
Copyright © 2011-2022 走看看