Python 遇到字符串时的递归生成器
这是我的密码:Python 遇到字符串时的递归生成器,python,python-3.x,recursion,generator,Python,Python 3.x,Recursion,Generator,这是我的密码: def flatten(nested): try: for sublist in nested: for element in flatten(sublist): yield element except TypeError: yield nested 这是Magus Lie Hetland写的一本书中的一个例子,该书名为《从新手到专业的Python入门》 它说,如果在这个列
def flatten(nested):
try:
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
这是Magus Lie Hetland写的一本书中的一个例子,该书名为《从新手到专业的Python入门》
它说,如果在这个列表中有一个字符串,它将是无限的递归。
是的,是真的。但是如果我用这个发电机,我该怎么办呢?我是一个新的学习者。谢谢你的教学。最后,我的英语很差,如果你努力阅读,我很抱歉。我会尽力提高的 无限递归发生在字符串的情况下,因为它是可伸缩的 您的函数依赖于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
)时,会发生类型错误,使函数脱离递归。但是,这不会发生在字符串中:
> 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
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
由于python仍将在单个字符串上迭代,并且函数依赖类型异常来停止递归,因此函数将无限期运行(直到达到最大递归深度且程序至少崩溃)
因此,如果要将此函数用于字符串,只需设置一个条件来检查函数是否在字符串上迭代:
> 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
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
无限递归发生在字符串的情况下,因为它是可伸缩的 您的函数依赖于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
)时,会发生类型错误,使函数脱离递归。但是,这不会发生在字符串中:
> 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
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
由于python仍将在单个字符串上迭代,并且函数依赖类型异常来停止递归,因此函数将无限期运行(直到达到最大递归深度且程序至少崩溃)
因此,如果要将此函数用于字符串,只需设置一个条件来检查函数是否在字符串上迭代:
> 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
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
我认为@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
我认为@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
好的,我已经找到了我的解决方案:
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
好的,我已经找到了我的解决方案:
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
我是第一次来这里。请帮帮我。另外,我发现了一件好事。我应该用四个空格而不是“
。我在这个页面上的代码看起来很糟糕。QAQ。我总是在降价时使用
。这是我第一次来。请帮帮我。另外,我发现了一件好事。我应该用四个空格而不是“。我在这个页面上的代码看起来很糟糕。QAQ。我总是用
降价。好的,谢谢你~我知道这个问题。但是如果我想通过你的方式收到一封信,我应该怎么做。例如,['hello',[3,4]-->['h','e','l','l','o',3,4]3Q,我已经找到了方法好的,谢谢你~我知道这个问题。但是如果我想通过你的方式收到一封信,我应该怎么做。例如,['hello',[3,4]]---->[h','e','l','l','o',3,4]3Q,我已经找到了路