所以,你正试图压平一个列表。你走在正确的道路上,但你犯了一些错误。他们来了。
移动你的try-except
inside循环。使用您的代码,如果TypeError
为一个元素引发,然后循环停止运行。你不希望这种事发生。
在尝试中,你一无所获。仅进行函数调用。您也应该从那里返回一些东西。我会推荐yield from
如果你有 python3.3+。
最后,在except
, 你需要yield element
, not toflatten
。不要给出整个列表。
def flatten(toflatten):
for element in toflatten:
try:
yield from flatten(element)
except TypeError:
yield element
这给出了,
>>> list(flatten([1,2,3,[4,5,6]]))
[1, 2, 3, 4, 5, 6]
您已经使用了 EAFP(请求宽恕比请求许可更容易),这很好。这是一种方法(实际上是我最喜欢的),但有一个缺点:这会在字符串上崩溃。
还有另一种方法:LYBL(三思而后行)。它包括更加谨慎,使用if
语句,这样就不会引发错误。
def flatten(toflatten):
for element in toflatten:
if isinstance(element, list):
yield from flatten(element)
else:
yield element
其工作原理与以前相同,并且给出,
>>> list(flatten([1,2,3,[4,5,6]]))
[1, 2, 3, 4, 5, 6]
然而,这是有利的,因为事实上yield from
生成器委托仅在子列表上调用。我有没有提到它也适用于字符串元素?
>>> list(flatten([1,2,3,[4,5,'abc']]))
[1, 2, 3, 4, 5, 'abc']
请注意,在任何一种情况下,如果您有递归定义的列表,则需要注意无限递归。例如,flatten
会因这种输入而崩溃。
x = [1, 2, 3]
x.append(x)
flatten(x)
你最终会得到一个运行时错误:
RuntimeError: maximum recursion depth exceeded