zoukankan      html  css  js  c++  java
  • Python 基础

    列表生成器/列表解析 list comprehension

    • 简单灵活地创建列表,通常和lambda(), map(), filter() 一起使用
    • 通过列表生成式, 直接创建列表。但是,收到内容限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问几个元素,那其他的就白占空间。列表生成器能够一边循环一边计算,大大节省大量的空间。是生成器的一种。 

    • 只有调用,才能生成。 不支持切片操作,只能通过__next()___一个个取数字。

    基本语法

    [expr for iter_var in iterable]
    or
    [expr for iter_var in iterable if cond_expr]

    案例

    # example 1:
    >>> [i*2 for i in range(10)]
    [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
    
    # example 2: 迭代3行5列的矩阵
    q = [(x+1, y+1) for x in range(3) for y in range(5)]
    print(q)
    list comp

    生成器

    定义

    生成器是列表生成器的一个扩展。 在python中,这种一边循环一边计算的机制,称为生成器 generator; 每次计算一个条目后,把这个条目“生成“(yield)出来, 这个过程成为”延迟计算“ (lazy evaluation),所以在使用内存上更有效。在语法上,生成器就是一个带yield语句的函数。

    生成器的特征:

    1. 只有调用才生成。 否则算法不占内存
    2. 生成器的调用,只能够记住当前位置。 可以同 generator.__next__() 方法来调用下一个对象,但是无法回到过去的位置。 可以for循环打印
    3. 不支持切片等列表操作,只能一个一个取

    yield函数使函数变生成器,是构建生成器的方法。 生成器的好处在于能够中途停下,附加其他功能,然后再继续调用。 

    应用:

    1. 调用函数中的一个值并跳出函数,下次进入继续调用下个值。以下面斐波拉契Fibonacci数列为例:

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b  # 知识点1 - yield的功能,返回一个值给调用者并暂停执行。
            a, b = b, a + b   # 重新赋值的过程, 左边的a,b是新生的, 右边的过去的值运算
            n = n + 1
        return "done"    # return 的作用是next调用时可能出现异常处理的返回值。
    
    print(fib(10))  # 返回变为一个generator: <generator object fib at 0x0000026FAA8A78E0>
    
    # 知识点2 - 调用元素的方式
    f = fib(10)
    for i in f:
        print(i)  # 用for循环,函数返回值done不会打印
    
    # 知识点3 - next()调用出现异常的情况
    g = fib(6)
    while True:
        try:
            x = next(g)     # 内置方法,= __next__一样。 当达到一个真正的返回或者函数结束没有更多的值返回,一个StopIteration异常将会抛出。所以需要处理异常,通过try ... expect... 语句
            print('g:',x)
        except StopIteration as e:
            print('Generator return value: ', e.value)   # e.value 返回的是 done

    2. 协同程序。协同程序是可以运行的独立函数调用,可以暂停或者挂起,并从程序离开的地方继续或者重新开始。在有调用者和(被调用者)协同程序也有通信。举例来说,当协同程序暂停的时候,我们能从其中获得一个中间的返回值,当调用回到程序中时,能够传入额外或者改变了的参数,但仍能够从我们上次离开的地方继续,并且所有状态完整。生成器的作用是挂起返回出中间值并多次继续的协同程序。

     1 #!usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 # 通过yield实现在单线程的情况下实现并发运算的效果,或者; 典型的生产者 - 消费者模型.这是以后异步IO的雏形。
     4 
     5 import time
     6 
     7 
     8 def consumer(name):
     9     print('%s 准备吃包子啦' %name)
    10     while True:
    11         baozi = yield   # yield
    12         print('包子[%s]来了,被[%s]吃了' %(baozi,name))
    13 
    14 
    15 def producer(name):
    16     c = consumer('A')   # 将函数变成生成器
    17     c2 = consumer('B')
    18     c.__next__()        # 第一次调用生成器
    19     c2.__next__()
    20     print('老子开始准备吃包子啦!')
    21     for i in range(10):
    22         time.sleep(1)
    23         print("做了2个包子!")
    24         c.send(i)   # send的作用是唤醒并给yield传值,next只是调用yield
    25         c2.send(i)
    26 
    27 producer("alex")
    最简单的协程 - 吃包子例子

    Reference

    1. Python之路,Day4 - Python基础4 (new版),http://www.cnblogs.com/alex3714/articles/5765046.html

    2. 《Python 核心编程 V2》page 205 - 207; page 305 - 307

  • 相关阅读:
    七十年前往事的回顾:偷窥造酒作坊的裸体男人
    Python画图工具matplotlib的安装
    版本号控制-搭建gitserver
    HDU 4405 概率期望DP
    下载jdk文件后缀是.gz而不是.tar.gz怎么办
    《小亚和小信》小强,你就长点心吧!
    7.11 小结
    动态规划 LCS,LIS
    每秒更新时间 v-text的应用 (解决闪现{}问题)
    vue 引入组件
  • 原文地址:https://www.cnblogs.com/lg100lg100/p/7282547.html
Copyright © 2011-2022 走看看