Python的生成器

Python的生成器_第1张图片

作者:金良([email protected]) csdn博客: http://blog.csdn.net/u012176591

展开任意层嵌套的列表

不使用生成器对象

flat_list = []
def flatten_if(nested,flat_list):
    try:
        nested[0]
    except: 
        flat_list.append(nested)
        #print nested
    else:
        for i in nested:
            flatten_if(i,flat_list)

思路:
对于要解析的对象,对其执行索引操作。如果出现异常,说明该对象是元素,而不是列表,所以将其收集起来;如果没有异常,说明该对象是列表,对其用flatten_if函数进一步解析。

执行效果
这里写图片描述

使用生成器

生成器小例子

任何包含yield语句的函数称为生成器。函数内部可以有多个yield 语句,返回多个值,并把它们封装成一个生成器对象,作为函数的返回对象。

生成器与迭代器比较类似,其有如下图所示的用法。每次产生一个值(即使用yield语句),函数会在该处冻结并等待唤醒。函数被唤醒后就从该冻结处继续执行。

这里写图片描述

 用生成器解析任意嵌套的列表

def flatten(nested):
    try:
        for sublist in nested:
            for element in flatten(sublist):
                yield element
    except TypeError:
        yield nested

这里写图片描述

对生成器解析过程的剖析

def flatten_depth(nested,depth):
    depth[0] += 1
    try:
        for sublist in nested:
            for element in flatten_depth(sublist,depth):
                yield 'not-'+str(element)
    except TypeError:        
        yield 'error-'+'Depth:'+str(depth[0])+'-'+'Element'+'::'+str(nested)
    depth[0] -= 1 

Python的生成器_第2张图片

def flatten_1only(nested,level):
    level[0] += 1
    try:
        for sublist in nested:
            for element in flatten_1only(sublist,level):
                level[0] -= 1
                yield 'not-'+str(level[0])+':'+str(element)
    except TypeError:
        level[0] -= 1
        yield 'error-'+str(level[0])+':'+str(nested)

八皇后问题

def conflict(state,nextX):
    #state是个元组,其元素表示对应地行的皇后的位置;
    #nextX是个元素,表示下一行要测试的皇后的安放位置;
    #该函数用来检测nextX是否与state冲突,即在前几行已经正确放置了皇后的情况下,
    #在下一行的nextX位置放置皇后是否冲突。
    nextY = len(state)
    for i in range(nextY):
        #对state中每个元素都检测是否冲突,即不同行,不同列,也不在对角线上。
        #不同行的条件是肯定满足的。
        #abs(state[i]-nextX) in (0,nextY-i)是判断是否冲突的语句,
        #其中abs(state[i]-nextX)=0表示z在同一列,
        #abs(state[i]-nextX) = nextY-i表示在对角线上,
        #排除了这两种情况,就可以确定不冲突。
        if abs(state[i]-nextX) in (0,nextY-i):
            return True
    return False

def queens(num=8,state=()):
    for pos in range(num):
        if not conflict(state,pos):
            if len(state) == num-1:
                yield (pos,)
            else:
                for result in queens(num,state+(pos,)):
                    yield (pos,)+result

执行效果:
Python的生成器_第3张图片

  • Lambda, filter, reduce and map http://www.python-course.eu/lambda.php
  • Python中的高级数据结构 http://blog.jobbole.com/65218/
  • 30 Python Language Features and Tricks You May Not Know About http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html
  • http://sahandsaba.com/python-classes-metaclasses.html
  • http://sahandsaba.com/python-decorators.html
  • http://sahandsaba.com/python-iterators-generators.html

你可能感兴趣的:(生成器)