这是我的代码:
def flatten(nested):
try:
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
这是一本书中的例子,该书由Magus Lie Hetland撰写,名为Beginning Python From Novice to Professional。
它说,如果这个列表中有一个字符串,它将通过递归无穷无尽。 是的,这是真的。但是,如果我使用这台发电机,我该怎么办?我是一个新学习者。谢谢你的教学。最后,我的英语很差,如果你努力阅读,我很抱歉。我会尽力改进。
答案 0 :(得分:2)
在字符串的情况下会发生无限递归,因为它是可迭代的。
你的函数依赖于TypeError来打破递归,所以这里代码通常是如何进行的:
> flatten([[1,2],[3,4]]) ---function call
> for e in ([[1,2],[3,4]]) ---outer loop
> for i in flatten([1,2]) ---inner loop
> for e in ([1,2]) ---recursion outer loop
> for i in flatten(1) ---recursion inner loop
> for e in 1 [TYPE_ERROR] ---recursion2 outer loop
> yield 1 ---recursion2 except call
> etc...
正如您所看到的,当程序尝试迭代整数(1
)时,会发生TypeError,导致函数无法递归。但是,这不会发生在字符串中:
> flatten([["hi","hello"],[3,4]]) ---function call
> for e in ([["hi","hello"],[3,4]]) ---outer loop
> for i in flatten(["hi","hello"]) ---inner loop
> for e in (["hi","hello"]) ---recursion outer loop
> for i in flatten("hi") ---recursion inner loop
> for e in "hi" ---recursion2 outer loop
> for i in flatten("h") ---recursion2 inner loop
> for e in "h" ---recursion3 outer loop
> for i in flatten("h") ---recursion3 inner loop
> and so on forever
因为python仍会迭代单个字符串,并且该函数依赖于类型异常来停止递归,所以该函数将无限期地运行(好吧,直到达到最大递归深度并且程序至少崩溃)。
因此,如果你想将这个函数用于字符串,你只需要创建一个条件来检查函数是否在字符串上迭代:
def flatten(nested):
try:
if isinstance(nested, str):
yield nested
else:
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
使用添加的if语句,您应该能够使用字符串:
mylist = [["hi","hello"],[3,4]]
for e in flatten(mylist):
print(e)
---Output---
hi
hello
3
4
答案 1 :(得分:0)
我认为@avghdev通过检查str
而不是检查list
犯了一个大错误 - list
是我们想要重复出现的积极情况。在所有其他情况下,我们希望产生普通值
下面,我们使用yield from
委托给另一台生成器。在这种情况下,我们的flatten
生成器是递归的,因为它会自行生成。
由于这项实施,该计划将消除痛苦和痛苦。
def flatten (xs):
for x in xs:
if isinstance (x, list):
yield from flatten (x)
else:
yield x
for x in flatten ([ 1, [ '2', [ 3, [ '4', [ 5, None ]]]]]):
print (x)
# 1
# 2
# 3
# 4
# 5
# None
答案 2 :(得分:0)
好的,我找到了解决办法:
def flatten(nested):
try:
if isinstance(nested, str):
for i in nested:
yield i
else:
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
lista = [[1, 2], 3, ['abc',[1, 'abc']]]
for i in flatten(lista):
print(i)
----Output----
1
2
3
a
b
c
1
a
b
c