generator保存的是算法,元素仅在使用的时候生成,占用内存小,总元素的个数可以是无限个。

简单的生成器与列表生成式,区别仅在于将中括号[ ],换成小圆括号( ).

In [1]: g=(x*x+2 for x in range(5))

In [2]: g

Out[2]: <generator object <genexpr> at 0x000002A3965CED00>

In [3]: next(g)

Out[3]: 2

In [4]: next(g)

Out[4]: 3

可以通过next()不断获得它的下一个返回值,直到没有元素了就会抛出StopIteration错误,一般情况下,会使用for语句循环。

for i in g:

print(i)

generator每次生成新的元素,都会根据上一个元素结束时的状态来生成,非常适合需要递归的算法,下一个元素根据上一个元素时的状态推演而出。

generator函数:如果一个函数中包含yield关键字,那它就是一个生成器函数。

generator函数的,在调用next()时执行,先正常执行,遇到yield返回yield后面的表达式,下次调用next()从yield处开始继续执行,直到元素全部返回完或遇到return 就会抛出StopIteration错误终止。如果generator函数中有return的值需要获取,可以通过捕获错误,输出错误的值来获取:

except StopIteration as e:

print(e.value)

使用generator求解8(N)皇后的所有解法 的算法:

def conflict(state,nextX):

"""判断当前选定的X坐标是否与之前的状态冲突"""

nextY=len(state)

for i in range(nextY):

if abs(state[i]-nextX)in(0,nextY-i):

return True

return False

def queens(num=8,state=()):

"""

返回值是在当前状态state下,剩下的num-len(state)行每行的X坐标组成的元组"""

if len(state)>num-1:

raise ValueError ("len(state) cann\'t be bigger than num-1" )

#尝试X的坐标值

for pos in range(num):

#如果相对于当前状态,下一行的x坐标不冲突

if not conflict(state,pos):

#如果剩下的需确定X坐标的行数num-len(state)为1,则返回该 单个X值的元组

if len(state)==num-1:

yield(pos,)

else:

#如果返回需返回X坐标的行数大于1,就返回(pos,)+【确定该行X 值得状态下,剩下num-len(state+(pos,))行每行X坐标组成的元组】,即(pos,)+result

for result in queens(num,state+(pos,)):

yield (pos,)+result

print(len(list(queens(8))),'*8**9*',len(list(queens(9))))

fh=queens(4)

for i in fh:

print(i)

此递归形式类似如下:

queens(n,state0)    =   pos1+queens(n,state1)

queens(n,state1)    =  pos2+queens(n,state2)

queens(n,state2)    =  pos3+queens(n,state3)

...

queens(n,staten-1)

=posn

由于queens(n,state1)的值可能有多个,而pos1的值也可能有多个,在递归式中只是选用了其中一个,故算法中使用了两个for循环。

yiled后面的返回表达式(pos,)+result  中result的值需要计算(计算过程就形同上面的递归过程,计算完后则返回)

当前状态的解较复杂,但可以等于F(下一个状态下的解)  F为一元函数,然后一直递归到最单一状态下的一个简单解时,就可以使用生成器的yield F(x+1) ,逐渐递归到 F(x+n)  ,  F(x+n)的值是固定

仅通过简单语句

def f(x):

if x=X+n:

yield 固定值

else:

yield F( f(x+1) )

上述程序中,如果满足条件的pos,和queens(num,state+(pos,))都只有一个,则程序中只有两个yield,则queens(num,state)最多返回两个元素。

突然想到上述递归,也可以采用return F(f(x+1))的方式来实现,但是

yield与return的区别在于,return 计算完其后得到表达式,函数就结束; 而yield 计算完其后的表达式,还可以继续返回第二个yield后面的表达式的值,直到所有的代码都运行完毕。

另外

普通函数调用会直接返回结果,而generator调用会返回一个generator实例,要通过for或next()获取其值:

f=abs(-4)

4

Python的generator生成器的更多相关文章

  1. Python学习笔记 - 生成器generator

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- # generator 生成器 L = [x * x for x in range(10)] print( ...

  2. Python高级语法之:一篇文章了解yield与Generator生成器

    Python高级语法中,由一个yield关键词生成的generator生成器,是精髓中的精髓.它虽然比装饰器.魔法方法更难懂,但是它强大到我们难以想象的地步:小到简单的for loop循环,大到代替多 ...

  3. Day10 python高级特性-- 生成器 Generator

    列表生成式可以创建列表,但是受内存限制,列表容量时有限的,创建一个巨量元素的列表,不仅占用很大的存储空间,当仅仅访问前几个元素时,后面的绝大多数元素占用的空间都被浪费了. 如果list的元素可以按照算 ...

  4. python高级之生成器&迭代器

    python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container):多个元素组织在一起的数据结构 可迭代对象( ...

  5. 【python】迭代器&生成器

    源Link:http://www.cnblogs.com/huxi/archive/2011/07/01/2095931.html 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素 ...

  6. Python基础 (yield生成器)

    如果在一个函数中使用了yield,那么这个函数实际上生成的是一个生成器函数 ,返回的是一个generator object.生成器是实现迭代的一种方式 特点: 其实返回的就是可以的迭代对象 和迭代的方 ...

  7. python 基础——generate生成器

    通过列表表达式可以直接生成列表,不过列表一旦生成就需要为所有元素分配内存,有时候会很消耗资源. 所以,如果列表元素可以按照某种算法推算出来,这样就不必创建完整的list,从而节省大量的内存空间. 在P ...

  8. 第三篇:python高级之生成器&迭代器

    python高级之生成器&迭代器   python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container ...

  9. python迭代器与生成器及yield

    一.迭代器(itertor) 1.可迭代: 在Python中如果一个对象有__iter__()方法或__getitem__()方法,则称这个对象是可迭代的(iterable). 其中__iter__( ...

随机推荐

  1. 地宫取宝|2014年蓝桥杯B组题解析第九题-fishers

    地宫取宝 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...

  2. Trailing Zeroes (III) (二分)题解

    You task is to find minimal natural number N, so that N! contains exactly Q zeroes on the trail in d ...

  3. The DELETE statement conflicted with the REFERENCE constraint

    Page是主表,主键是pageid:UserGroupPage表中的PageID字段是Page表里的数据. https://www.codeproject.com/Questions/677277/I ...

  4. 【附5】springboot之配置文件

    本文转载自http://www.jianshu.com/p/80621291373b,作者:龙白一梦 我的boss 代码从开发到测试要经过各种环境,开发环境,测试环境,demo环境,线上环境,各种环境 ...

  5. mysql链接 显示 error: 'Access denied for user 'root'@'localhost' (using password: NO)'

    解决方案 https://stackoverflow.com/questions/2995054/access-denied-for-user-rootlocalhost-using-password ...

  6. HDU 5889 Barricade(最短路+最小割)

    http://acm.hdu.edu.cn/showproblem.php?pid=5889 题意: 给出一个图,帝国将军位于1处,敌军位于n处,敌军会选择最短路到达1点.现在帝国将军要在路径上放置障 ...

  7. POJ 1753 Flip Game(bfs+位压缩运算)

    http://poj.org/problem?id=1753 题意:一个4*4的棋盘,只有黑和白两种棋子,每次翻转一个棋子,并且其四周的棋子也跟着翻转,求棋盘全为黑或全为白时所需的最少翻转次数. 思路 ...

  8. Codeforces Round #323 (Div. 2) D. Once Again... 乱搞+LIS

    D. Once Again... time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  9. 强大的Manage

    Queue和Pipe实现的数据共享方式只支持两种结构 Value 和 Array.Python中提供了强大的Manage专门用来做数据共享,其支持的类型非常多,包括: Value,Array,list ...

  10. VcCallC#_01

    1.C# 代码: using System; using System.Collections.Generic; //using System.Linq; using System.Text; //u ...