列表生成式

a = [i+1 for i in range(10)]
print(a)

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

这就是列表生成式

生成器(generator)

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。

如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的    list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(generator)。

# 列表生成式:
L = [x * x for x in range(10)]
print(L)
# 生成器:
g = (x * x for x in range(10))
print(g)

输出结果:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<generator object <genexpr> at 0x00000267824C0258>

list可以直接打印出结果,但是generator只能通过next()获得下一个返回值

g = (x * x for x in range(4))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

输出结果:

0
1
4
9

Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
StopIteration

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

生成器示例:

def fib(max_n):                            # 斐波那契数列生成器
    n, a, b = 0, 0, 1
    while n < max_n:
        yield b                            # 函数中出现yield则函数变成生成器
        a, b = b, a+b
        n = n+1
    return "done"

f = fib(6)
print(f.__next__())                        # 生成器生成一个数(f.__next__()=next(f))
print("______")                            # 生成器无法返回,之后生成的数据不包含以上的数

while True:
    try:
        x = next(f)                        # 循环生成数列
        print("f:", x)                     # 输出计算结果
    except StopIteration as e:             # 当循环次数大于max_n时,运行以下
        print("Generator return value:", e.value)
        break

输出结果:

1
______
f: 1
f: 2
f: 3
f: 5
f: 8

当函数中出现 ‘yield’ 时这个函数就成了一个 generator 的函数

generator在执行的时候遇到 yield 时会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

通过yield实现在单线程的情况下实现并发运算的效果:

import time

def consumer(name):
    print("%s开始吃包子了" % name)
    while True:
        produce = yield                                # 函数在此暂停,等待唤醒
        print("%s吃了%i个包子" % (name, produce+1))      # 唤醒后执行

def producer(name):
    c = consumer("A")
    c2 = consumer("B")
    c.__next__()
    c2.__next__()
    print("%s准备开始生产" % name)
    for i in range(3):
        time.sleep(1)
        print("已经做了%i个包子" % (i+1))
        c.send(i)                                       # 将i发送给produce,并唤醒函数
        c2.send(i)

producer("C")

输出结果:

A开始吃包子了
B开始吃包子了
C准备开始生产
已经做了1个包子
A吃了1个包子
B吃了1个包子
已经做了2个包子
A吃了2个包子
B吃了2个包子
已经做了3个包子
A吃了3个包子
B吃了3个包子

在 producer 函数中 c 和 c2 轮流调用 consumer 函数

send() 和 next() 一样可以唤醒生成器,而且还能给 yield 传值

迭代器

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如list、tuple、dict、set、str等;

一类是generator,包括生成器和带 yield 的 generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。

可以使用isinstance()判断一个对象是否是Iterable对象

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

*可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator.

生成器都是Iterator对象,但list、dict、str 虽然是 Iterable ,却不是Iterator。
把list、dict、str 等 Iterable 变成Iterator可以使用 iter() 函数.

 

 

Python生成器(generator)和迭代器(Iterator)的更多相关文章

  1. python生成器(generator)、迭代器(iterator)、可迭代对象(iterable)区别

    三者联系 迭代器(iterator)是一个更抽象的概念,任何对象,如果它的类有next方法(next python3)和__iter__方法返回自己本身,即为迭代器 通常生成器是通过调用一个或多个yi ...

  2. Python 生成器 Generator 和迭代器 Iterator

    #最近一周刚开始接触python,基本的语法,和使用特性和Java差别还是蛮大的. 今天接触到Python的迭代器和生成器有点不是很明白,所以搜索了先关资料整理了一些自己的理解和心得 简述(Profi ...

  3. 生成器generator和迭代器Iterator

    一.列表生成式       在学习生成器迭代器之前先了解一下什么是列表生成式,列表生成式是Python内置的非常简单却强大的可以用来创建list的生成式.什么意思?举个例子,如果想生成列表[0,1,2 ...

  4. Python之生成器(generator)和迭代器(Iterator)

    generator 生成器generator:一边循环一边计算的机制. 生成器是一个特殊的程序,可以被用于控制循环的迭代行为.python中的生成器是迭代器的一种,使用yield返回值函数,每次调用y ...

  5. Python中生成器generator和迭代器Iterator的使用方法

    一.生成器 1. 生成器的定义 把所需要值得计算方法储存起来,不会先直接生成数值,而是等到什么时候使用什么时候生成,每次生成一个,减少计算机占用内存空间 2. 生成器的创建方式 第一种只要把一个列表生 ...

  6. 【python之路29】python生成器generator与迭代器

    一.python生成器 python生成器原理: 只要函数中存在yield,则函数就变为生成器函数 #!usr/bin/env python # -*- coding:utf-8 -*- def xr ...

  7. 学习python第十二天,函数4 生成器generator和迭代器Iterator

    在Python中,这种一边循环一边计算的机制,称为生成器:generator 要创建一个generator,有很多种方法.第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个genera ...

  8. Python 生成器 (generator) & 迭代器 (iterator)

    python 生成器 & 迭代器 生成器 (generator) 列表生成式 列表生成式用来生成一个列表,虽然写的是表达式,但是储存的是计算出来的结果,因此生成的列表受到内存大小的限制 示例: ...

  9. 【Python之路】特别篇--生成器(constructor)、迭代器(iterator)、可迭代对象(iterable)

    生成器(constructor) 生成器函数在Python中与迭代器协议的概念联系在一起.包含yield语句的函数会被特地编译成生成器 !!! 当函数被调用时,他们返回一个生成器对象,这个对象支持迭代 ...

  10. Python学习笔记014——迭代器 Iterator

    1 迭代器的定义 凡是能被next()函数调用并不断返回一个值的对象均称之为迭代器(Iterator) 2 迭代器的说明 Python中的Iterator对象表示的是一个数据流,被函数next()函数 ...

随机推荐

  1. Selenium如何在谷歌浏览器模拟H5页面

    一.基于java语言(转载:http://www.mamicode.com/info-detail-1972340.html) public class runtest { WebDriver dri ...

  2. MVC _Ajax的使用【七】

    一.本篇主要写的是在MVC项目中一种ajax的使用方法 1.  首先在控制器中创建两个方法,showCreate()和AddUserInfo() using System; using System. ...

  3. 19、Squid代理服务器

    第十九章,配置Squid服务器 一.代理服务器简介 19.1.1:什么是代理服务器 代理服务器的功能就是代理网络用户去取的网络信息,好比是网络信息的中转站,大多被用来连接互联网和局域网.代理服务器好像 ...

  4. Android app图标总是显示默认的机器人图标,且在manifest文件的application中修改无效...

    问题描述:我使用的开发工具是eclipse,Android app默认的图标是一个机器人,如下图所示 现在我要将app的图标修改成另外一个图标: 探索过程: 首先想到修改Manifest文件中的app ...

  5. 『TensorFlow』读书笔记_Inception_V3_下

    极为庞大的网络结构,不过下一节的ResNet也不小 线性的组成,结构大体如下: 常规卷积部分->Inception模块组1->Inception模块组2->Inception模块组3 ...

  6. openLDAP安装时无法操作根节点数据,提示的是This base cannot be created with PLA.

    1.无法操作根节点数据,提示的是This base cannot be created with PLA. 解决办法 1)添加一个base.ldif文件,里面的dc和配置文件里的保持一致即可 dn: ...

  7. String 的方法总结

    1.charCodeAt方法返回一个整数,代表指定位置字符的Unicode编码.    strObj.charCodeAt(index)    var str = "ABC";   ...

  8. Linux获取so/ko文件版本号教程

    一.需要获取版本号的原因 从使用角度而言,有时只有特定版本的库才支持某些功能,所以我们需要确定库文件版本号. 从安全加固角度而言,有些版本存在漏洞有些版本不存在漏洞,所以我们需要获取版本号以确定当前使 ...

  9. python信号量

    同进程的一样 Semaphore管理一个内置的计数器,每当调用acquire()时内置计数器-1:调用release() 时内置计数器+1:计数器不能小于0:当计数器为0时,acquire()将阻塞线 ...

  10. tensoFlow之DNN文本分类

    TensorFlow文本分类: 亲测可用:https://blog.csdn.net/u012052268/article/details/77862202 简单实例:https://www.leip ...