zoukankan      html  css  js  c++  java
  • Python3的生成器generator(1)

    虽然生成器可以让你编写出优雅的代码,但它并不是不可或缺的。

    生成器是一种使用普通函数语法定义的迭代器。

    例1:创建一个将嵌套列表展开的函数

     1 # 创建一个将嵌套列表展开的函数
     2 # 给出的嵌套列表 nested:嵌套
     3 nested = [[1,2],[3,4]]
     4 
     5 def flatten(nested):
     6     for sublist in nested:
     7         for element in sublist:
     8             yield element  # yield每生成一个值后,函数都将冻结,被重新唤醒后,函数将从停止的地方开始继续执行
     9 
    10 for n in flatten(nested):
    11     print(n)

    输出:

    1

    2

    3

    4

    当然我们可以将for循环换成:

    print(list(flatten(nested)))

    输出:[1, 2, 3, 4]

    例2:递归生成器

    1 # 创建一个能够处理任意层嵌套的列表
    2 def flatten(nested):
    3     try:
    4         for sublist in nested:
    5             for element in flatten(nested):
    6                 yield element
    7     except TypeError:
    8         yield nested

    处理递归时,有两种可能:基线条件和递归条件

    基线条件下,要求这个函数展开单个元素(如一个数)。这种情况下,for循环将引发TypeError异常(因为你试图迭代一个数),而这个生成器只生成一个元素。

     如果要展开的是一个列表(或其他任何可迭代的对象),则需要:遍历所有的子列表(有些可能不是列表)并对它们调用flatten,然后使用另一个for循环展开后的子列表中的所有元素。

    注意:

    如果nested是字符串或类似字符串的对象,它就属于序列,因此不会引发TypeError异常,可你并不想对其进行迭代。

    因为:

    ① 你想将类似于字符串的对象视为原子值,而不是应该展开的序列;

    ② 对这样的对象迭代会导致无穷递归。因为字符串的第一个元素是一个长度为1的字符串,而长度为1的字符串的第一个元素是字符串本身。

    要处理这种问题,必须在生成器开头进行检查。

    例3:添加检查对象是否类似于字符串

     1 def flatten(nested):
     2     try:
     3         # 不迭代类似字符串的对象
     4         try: nested + ''
     5         except TypeError: pass
     6         else: raise TypeError
     7         for sublist in nested:
     8             for element in flatten(nested):
     9                 yield element
    10      except TypeError:
    11         yield nested

    如果表达式nested + ''引发了TypeError异常(说明nested不是类字符串对象),就忽略这种异常;

    如果没有引发(说明nested是类字符串对象),则通过else引发。这样将在外部的except子句中原封不动地生成类似于字符串的对象(因为加的''对原字符串没有任何影响)。

    当然,我们也可通过isinstance检查

    例4:通用生成器

    生成器是包含yield关键字的函数,但被调用时不会执行函数体内的代码,而是返回一个迭代器。

    每次请求值时,都将执行生成器的代码,直到遇见yield或者return。

    yield意味着应生成一个值;

    return意味着生成器应停止执行(即不在生成值;当且仅当在生成器调用return时,才能不提供任何参数)

  • 相关阅读:
    《人月神话》读后感
    软件工程心得体会(十一)
    Arch + Win10 EFI 引导重装记录
    BurpSuite 的使用
    Wireshark 的使用
    Android 中的反调试技术
    IDA 对 so 的动态调试
    Smail 中的一些点
    IDA 对 SO 的逆向
    动态调试smali代码
  • 原文地址:https://www.cnblogs.com/gepu1991/p/9147593.html
Copyright © 2011-2022 走看看