zoukankan      html  css  js  c++  java
  • Python初学者第二十四天 函数进阶(3)生成器

    24day

    1、列表生成式:

    循环模式:[变量(加工后的变量) for 变量 in iterable]

    print([i for i in range(0,101,2)])
    [1,4,9,16,25,36,49]
    print([i*i for i in range(1,8)])
    #['python1期', 'python2期', .....'python20期']
    print(['python%s期'%i for i in range(1,21)])

    筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]

    [变量(加工后的变量) for 变量 in iterable if 条件]
    print([i for i in range(1,31) if i % 3 == 0])
    print([i for i in range(1,31) if i % 3 == 0])
    30以内能被2整除的数的平方
    print([ i*i for i in range(1,31) if i % 2 == 0])
    [1,2,3,4,6,7,8]
    print([i for i in range(1,9)if i != 5])
    l1 = ['wusir','ba', 'aa' ,'alex']
    过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
    print([i.upper() for i in l1 if len(i) > 3])
    ['WUSIR','ALEX']
    names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
             ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
    将列表中的至少含有两个'e'的人名留下来。
    l1 = []   
    for l in names:   #正常情况
        for name in l:
            if name.count('e') >= 2:
                l1.append(name)
    print(l1)
    print([j for i in names for j in i if j.count('e')==2])  #列表生成式


     1 >>> a = [i+1 for i in range(10)]
     2 >>> a
     3 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
     4 >>> a = [i+1 for i in range(10)]
     5 >>> a
     6 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
     7 >>> a = [i+1 for i in a]
     8 >>> a
     9 [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    10 >>> a = [i+1 for i in a]
    11 >>> a
    12 [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

    通过列表生成式,我们可以直接创建一个列表

    2、生成器:generator

    生成器特性:

    - 不占内存

    - 只能向前,不能返回

    - 当生成器达到要求会报错

    创建generator,方法一:一个列表生成式的[]改成(),就创建了一个generator

    >>> a3 = (i for i in range(5))
    >>> a3
    <generator object <genexpr> at 0x0000000001DF5BA0>
    >>> next(a3)
    0
    >>> next(a3)
    1
    >>> next(a3)
    2
    >>> next(a3)
    3
    >>> next(a3)
    4
    >>> next(a3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration

    通过for循环来调用生成器

    >>> a3 = (i for i in range(5))
    >>> for i in a3:
    ...     print(i)
    ...
    0
    1
    2
    3
    4

    通过while循环来调生成器(跳出循环会报错)

    >>> a3 = (i for i in range(5))
    >>> while True:
    ...     next(a3)
    ...
    0
    1
    2
    3
    4
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    StopIteration

    方法二:使用yield创建生成器(一个函数中包含yield关键字,那么这个函数就不在是一个普通的函数,而是一个generator)

    generator和函数不一样。函数是按顺序执行,遇到return语句或最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时会从上一次返回的yield语句处继续执行。

    return VS yield 

    return :返回并中止function

    yield :返回数据,并冰冻当前的执行过程。next唤醒冻结的函数执行过程,直到遇到下一个yield

     1 def fib(max):
     2     n,a,b = 0,0,1
     3     while n < max:
     4         yield b   #把函数的执行过程冻结在这一步,并且把b的值,返回给外面的next
     5         print(b)
     6         a,b = b,a+b
     7         n += 1
     8     return 'done'
     9 
    10 f = fib(10)
    11 next(f)
    12 next(f)
    13 next(f)

     当函数里面存在同时存在yield和return时,return值无法返回

     1 def range2(n):
     2     count = 0
     3     while count < n:
     4         print('count',count)
     5         count += 1
     6         yield count
     7     return 33333
     8 
     9 new_range = range2(3)
    10 n1 = next(new_range)
    11 n2 = next(new_range)
    12 n3 = next(new_range)
    13 n4 = next(new_range)

    #执行结果如下

    Traceback (most recent call last):
    count 0
    count 1
    count 2
    File "D:/编辑的文本/生成器.py", line 27, in <module>
    n4 = next(new_range)
    StopIteration: 33333

     3、生成器send

     1 def range2(n):
     2     count = 0
     3     while count < n:
     4         print('count',count)
     5         count += 1
     6         sign = yield count
     7         print('sign',sign)
     8     return 33333
     9 
    10 new_range = range2(3)
    11 n1 = next(new_range)
    12 new_range.send('stop')

    #执行结果:

    count 0
    sign stop
    count 1

    send------>>>>a、唤醒并继续执行;b、发送一个信息到生成器内部;

     总结:

    列表推导式 与生成器表达式区别;
    1,列表推导式 一行搞定,构建简单。
    2, 不能用debug排错,比较复杂的列表列表推导式不能推导出来。

    生成器表达式:
    1,循环模式。 (变量(加工后的变量) for 变量 in iterable)
    (变量(加工后的变量) for 变量 in iterable if 条件)
    1,一行搞定。
    2,节省内存。
  • 相关阅读:
    setTimeout中0毫秒延时
    javascript中call和apply方法
    javascript闭包
    apns 服务
    新的开始,新的起点
    心情笔记
    如何解决控件附件上传时超大附件无法上传的问题
    BPM实例分享——日期自动计算
    BPM实例分享——金额规则大写
    分享一个程序猿在流程数据查看权限问题的总结
  • 原文地址:https://www.cnblogs.com/fany-mok/p/8395227.html
Copyright © 2011-2022 走看看