生成器

列表生成式

用于快速地生成一个列表

a = [x*x for x in range(1,9)]
print(a) #输出[1, 4, 9, 16, 25, 36, 49, 64]

也可以用于生成函数结果的列表

def f(n):
return n**3 a = [f(x) for x in range(1,9)]
print(a) #输出[1, 8, 27, 64, 125, 216, 343, 512]

  

迭代器

迭代器是一个带状态的对象,他能在你调用 next() 方法的时候返回容器中的下一个值,任何实现了 __next__()方法的对象都是迭代器。

拿斐波拉契数列作例子

def fib(max):
L = []
n, a, b = 0, 0, 1
while n < max:
L.append(b)
a, b = b, a + b
n = n + 1
return L

  这种用法会如果max的很大的话会占用特别多的内存,导致程序卡顿。

使用迭代器可以解决复用可占空间的问题

迭代器可以通过 next() 不断返回数列的下一个数,内存占用始终为常数。

class Fib(object):
def __init__(self, max):
self.max = max
self.n, self.a, self.b = 0, 0, 1 def __iter__(self):
return self def next(self):
if self.n < self.max:
r = self.b
self.a, self.b = self.b, self.a + self.b
self.n = self.n + 1
return r
raise StopIteration()

  

生成器

生成器其实是一种特殊的迭代器。生成器(yield)既可以保持代码的简洁性,又可以减少占用内存的效果。它不需要再像上面的类一样写 __iter__() 和 __next__() 方法了,只需要一个 yiled 关键字。

def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1 for n in fib(5):
print(n) #输出
1
1
2
3
5

  yield 的作用就是把一个函数变成一个生成器,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个生成器,在 for 循环执行时,每次循环都会执行 fib 函数内部的代码,执行到 yield b 时,fib 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

(1)send()方法

send方法可以往生成器里传值

def f():
print("ok")
n = yield
print(n)
print("ok2")
yield 2
f = f()
f.send(None)
f.send(1)
next(f)
#输出
ok
Traceback (most recent call last):
1
ok2
File "D:/PyCharm Project/test/Starter/test2.py", line 10, in <module>
next(f)
StopIteration

  send方法会把值传到yield前的对象,并往下执行到下一个yield。但当使用send之前要先用next或者用send(None)来获取yield的位置,否则无法把值传给yield。

还有一点:

在一个生成器中,如果没有return,则默认执行到函数完毕;如果遇到return,如果在执行过程中 return,则直接抛出 StopIteration 终止迭代。而for不报错的原因是内部处理了迭代结束的这种情况。

是一个带状态的对象,他能在你调用 next() 方法的时候返回容器中的下一个值,任何实现了 __next__() (python2中实现 next() )方法的对象都是迭代器

从零开始的Python学习Episode 12——迭代器&生成器的更多相关文章

  1. Python学习---装饰器/迭代器/生成器的学习【all】

    Python学习---装饰器的学习1210 Python学习---生成器的学习1210 Python学习---迭代器学习1210

  2. python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化

    生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: >>> g = (x * x for xin range(10)) >>> ...

  3. 从零开始的Python学习Episode 15——正则表达式

    正则表达式 正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现,所以使用时要导入re模块.正则表达式模式被编译成一系列的字节码 ...

  4. 从零开始的Python学习Episode 13——常用模块

    模块 一.time模块 时间戳(timestamp) :时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量. 元组(struct_time)   :struct_time元组共有9 ...

  5. 从零开始的Python学习Episode 23——进程

    ---恢复内容开始--- 进程 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程.Python提供了非常好用 ...

  6. 从零开始的Python学习Episode 22——多线程

    多线程 线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. ...

  7. 从零开始的Python学习Episode 21——socket基础

    socket基础 网络通信要素: A:IP地址   (1) 用来标识网络上一台独立的主机 (2) IP地址 = 网络地址 + 主机地址(网络号:用于识别主机所在的网络/网段.主机号:用于识别该网络中的 ...

  8. 从零开始的Python学习Episode 20——面向对象(3)

    面向对象之封装 封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体. 隐藏 在python中用双下划线开 ...

  9. 从零开始的Python学习Episode 19——面向对象(2)

    面向对象之继承 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称 为基类或超类,新建的类称为派生类或子类. 子类会“”遗传”父类的属性,从而解决代码重用问 ...

随机推荐

  1. php生成word文档

    使用fopen文件操作函数来做,需要注意的直接生成中文文件名会乱码,(生成word和微软的编码不一样)需要转码生成.word内容保持utf8编码就好. $file_name = iconv(" ...

  2. 【最新最全】为 iOS 和 Android 的真机和模拟器编译 Luajit 库

    编译 Luajit 库,的确是一个挑战.因为官网的教程,在当前版本的 Xcode 和 NDK 环境中,已经不适用了.以前只是编译了适用于真机的 Luajit 库.最近在尝试编译模拟器 Luajit 库 ...

  3. eclipse 打开一个新工程的基本设置

    1.代码自动提示 Window -> Preferences -> Java -> Editor -> Content Assist -> Auto Activation ...

  4. jdk 配置

    JDK (绿色版)      此次安装的 JDK 版本为  1.8.0_77 步骤一: 拷贝 JDK(350M左右)到电脑 步骤二: 配置环境变量  JAVA_HOME  , PATH  ,  CLA ...

  5. Delphi 的TStringBuilder防止服务器内存碎片化

    Delphi 2009+ 的 System.SysUtils提供了一个类似.Net的StringBuilder,用于存储字符数组. 很多人不明白为什么要用TStringBuilder, Delphi中 ...

  6. STM32(6)——USART串口的使用

    1. 串口的基本概念 在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用 ...

  7. Kafka消息系统

    一.基本概念 Kafka是一个分布式的.可分区的.可复制的消息系统.它提供了普通消息系统的功能,但具有自己独特的设计. 首先让我们看几个基本的消息系统术语: Kafka将消息以topic为单位进行归纳 ...

  8. 双端队列 ADT接口 链表实现

    Deque ADT接口 DEQUEUE.h: #include <stdlib.h> #include "Item.h" typedef struct DEQUEUEn ...

  9. Could not connect to '192.168.80.145' (port 22): Connection failed的解决办法(远程连不上xshell)

    问题状况表现1 这个问题一般是你 的什么配置影响了虚拟机的网卡网关设置!!!. 问题状况表现2 这个问题一般是你 的什么配置影响了虚拟机的网卡网关设置. 解决办法 网上的那些解决方案,我都试过,比如. ...

  10. 20155215 《Java程序设计》实验一(Java开发环境的熟悉)实验报告

    20155215 <Java程序设计>实验一(Java开发环境的熟悉)实验报告 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑 ...