从零开始的Python学习Episode 12——迭代器&生成器

生成器

列表生成式

用于快速地生成一个列表

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() )方法的对象都是迭代器

原文地址:https://www.cnblogs.com/smilepup-hhr/p/9788894.html

时间: 2024-11-05 23:27:05

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

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

Python学习---装饰器的学习1210 Python学习---生成器的学习1210 Python学习---迭代器学习1210 原文地址:https://www.cnblogs.com/ftl1012/p/9484145.html

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

生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: 1 >>> g = (x * x for xin range(10)) 2 >>> g3 <generator object <genexpr> at 0x1022ef630> 此处g就是一个生成器. 迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是gene

从零开始的Python学习Episode 11——装饰器

装饰器 装饰器是用来处理其他函数的函数,主要作用是在不修改原有函数的情况下添加新的功能,装饰器的返回值也是一个函数对象. 简单的装饰器 1 import time 2 3 def show_time(f): 4 def inner(): 5 start = time.time() 6 f() 7 end = time.time() 8 print('time: %s'%(end-start)) 9 return inner 10 11 @show_time 12 def fun1(): 13 p

从零开始的Python学习Episode 7——文件基本操作

文件基本操作 一.打开文件 f = open('11','r')#open('file path','mode') 创建一个文件对象 文件有多种打开模式: 1. 'r':新建一个文件对象以只读方式打开文件.读文件的指针将会放在文件的开头. f = open('11','r')#open('file path',mode') data = f.read() print(data)f.close() #输出123456789 2.'w':新建一个只用于写文件的文件对象 f = open('11','

从零开始的Python学习Episode 10——函数

函数 一.函数的创建 简单格式 def function_name(参数表): 函数体 return 如果没有写return,函数会默认返回一个none 二.函数的参数 必需参数: 调用函数时必需参数须以正确的顺序传入,调用的数量必须和声明时的一样. def func1(name,age): print('my name is %s,i am %d years old'%(name,age)) func1('smilepup',20) #输出my name is smilepup,i am 20

从零开始的Python学习Episode 14——日志操作

日志操作 一.logging模块 %(message)s 日志信息 %(levelno)s 日志级别 datefmt 设置时间格式 filename 设置日志保存的路径 level 设置日志记录的级别 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为"a"还可指定为"w","a"表示在原有的日志之后增添日志,"w"表示清除原有的日志后再添加新的日志. 配置日志级别.日志格式.输出位置 impor

从零开始的Python学习Episode 17——序列化

序列化 我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语 言中也被称之为serialization,marshalling,flattening等等,都是一个意思. 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上. 反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling. json 如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好 的方法是序列

从零开始的Python学习Episode 5——字典

字典 字典是另一种可变容器模型,且可存储任意类型对象. 一.添加 (1)直接添加 dict={'name':'smilepup'} dict['age']=20 dict['name']='piggy' print(dict) #输出{'name': 'piggy', 'age': 20} 若输入的键存在,就把键对应的值更新为新的值. 若输入的键不存在,就把输入的键值对添加进字典. (2)setdefault()方法 dict={'name':'smilepup'} a = dict.setde

Python装饰器、迭代器&amp;生成器、re正则表达式、字符串格式化

Python装饰器.迭代器&生成器.re正则表达式.字符串格式化 本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能. 先定义一个基本的装饰器: ########## 基本装饰器 ########