def flatten(nested): try: try: nested + '' except TypeError: pass else: raise TypeError for sublist in nested: for element in flatten(sublist): yield element except TypeError: yield nested >>> list(flatten(['foo',['bar',['baz']]])) ['foo', 'bar', 'baz']
请教大家以上程序在输入list(flatten(['foo',['bar',['baz']]]))后是如何运行的
1 通过递归调用一层层打开嵌套的表,取出元素
2 将元素与空白字符串相加,如果有TypeError,说明是表,那么继续递归调用
如果没有TypeError, 说明该元素是字符串,通过raise错误来停止递归,并返回该元素
这个写法非常奇怪
第一次执行:['foo',['bar',['baz']]] + ' ' 出错,由于except TypeError 子句中是pass,所以接下来执行for循环中的内容,在这个嵌套的for循环中,应该怎么执行?
@haojinming:
在循环中,对元素执行flatten
题主问的应该是生成器的用法吧?
python 解释器运行到 yield 后会立即返回 yield 后的值,但是函数本身不会被清理,下次进入的时候直接从返回的地方继续运行,这个就是生成器的原理。
flatten返回了一个生成器(因为函数中有 yield 关键字),生成器是可以遍历的,遍历生成器的时候 for 循环会自动调用 next,next 会调用 生成器的 send,驱动生成器从上次返回的地方继续运行,一直到结束为止。
但是这个函数有两个问题:
1,用过与字符串相加来做类型约束非常不好,不如直接判定类型
2,第二层for循环是不必要的,直接用 yield from 就好了