遇到字符串时的递归生成器

2024-05-23 16:50:52 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的密码:

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

这是Magus Lie Hetland写的一本名为《从新手到专业的Python入门》的书中的一个例子。你知道吗

它说,如果在这个列表中有一个字符串,它将是无限的递归。 是的,是的是的,但是如果我用这个发电机该怎么办?我是新来的学习者。谢谢感谢你的教诲。最后,我的英语很差,我很抱歉,如果你努力阅读。我会尽力提高的。你知道吗


Tags: in密码fordefelementnestedyieldtry
3条回答

无限递归发生在字符串的情况下,因为它是iterable。你知道吗

您的函数依赖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

因为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

好的,我已经找到了解决办法:

 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

我认为@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

相关问题 更多 >