可以用递归完成吗?

时间:2012-03-16 18:54:05

标签: python recursion

我试图让我的程序按照我想要的方式运行,但是我遇到了一些麻烦,希望有人可以帮忙。

我写了一个程序,它接受一个字符列表并组装它们来创建单词。当列表中有“”时,Word结束。所以它看起来像是:

inp = ['r','e', 'e', 'l', ' ', 'y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k']
outp = ['reel', 'yellow', 'gel', 'peek']

代码如下所示:

def mer(inp, outp=[]):
    tail = 0
    for item in inp:
        if item == (" "):
            inp[:tail] = ["".join(inp[:tail])]
            outp.append(inp.pop(0))
            inp.remove(item)
        if ((" ") in inp) == False:
            inp[:] = ["".join(inp[:])]
            outp.append(inp.pop(0))        
        tail +=1

现在要获得输出(在输入就像在顶部的情况下)我需要调用mer两次。有没有办法使它运行,直到输入列表为空,或者可能使用递归?

这只是一项编程练习,所以它可能都做得更好,但就目前而言,我只需要这些。

4 个答案:

答案 0 :(得分:4)

您可以使用joinsplit

>>> ''.join(inp).split()
['reel', 'yellow', 'gel', 'peek']

# recursion
from itertools import takewhile

def fun(x):
    if not x:
        return
    y = list(takewhile(lambda i:i!=' ', x))
    yield ''.join(y)
    for z in fun(x[len(y)+1:]):
        yield z

list(fun(['r','e', 'e', 'l', ' ', 'y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k']))

答案 1 :(得分:3)

我知道你要求使用递归的方法,但在这种情况下,最pythonic方法是将字符连接在一起,然后拆分它们。

outp = "".join(input).split(" ")

答案 2 :(得分:2)

你肯定应该使用joinsplit,但由于这个问题专门要求递归解决方案,所以这里有一个使用一个的答案。

这仅仅是一种递归练习,不应使用此代码。

def join_split(inp, outp=None):
    if not inp:
        return outp
    if inp[0] == ' ':
        return join_split(inp[1:], (outp or ['']) + [''])
    if outp is None:
        return join_split(inp[1:], [inp[0]])
    outp[-1] += inp[0]
    return join_split(inp[1:], outp)

>>> join_split(['r','e', 'e', 'l', ' ', 'y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k'])
['reel', 'yellow', 'gel', 'peek']

答案 3 :(得分:2)

  

现在要获得输出(在输入就像在顶部的情况下)我需要调用mer两次。

您的算法的问题在于您在迭代时修改列表。这是一件顽皮且不安全的事情。

"reel"放入outp后,inp['y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k']。但是循环检查的下一个字符是 - 至少在CPython实现中 - 不是'y'的{​​{1}},而是'yellow'。这是因为迭代在内部存储了一个索引(恰好与您手动更新的'w'变量同步)并使用它来获取元素。在幕后创建实现for循环的tail完全没有意识到它正在迭代的listiterator的变化,因此无法调整以保持“相同位置”(谁知道无论如何你真正的意思是什么?)。

如果您在代码中添加了几个“跟踪”list语句,以便在各个点显示变量的状态,您可以自己查看。

无论如何,由于迭代器此时位于print,它会找到下一个空格并提取'w'就好了;但接下来它会移到'yellow'的{​​{1}},错过'k'之后的空格,并且它也不会在你的第二个if-case中运行任何代码,因为"peek"'gel'之间的空格仍在缓冲区中(您对真实结束条件的评价并不是很清楚。)

如果你真的,真的想要尽一切努力而不是只写'gel',你可以通过跟踪单词词头和词尾结束索引来修复问题,切出子列表,加入它们并将结果单词放入输出中,单独输入。我们正在努力:

  • 函数应该使用返回值来返回数据;传入'peek'参数很愚蠢 - 让我们只返回一个单词列表。

  • 我们可以使用内置的''.join(inp).split(' ')函数来获取与迭代时列表元素匹配的索引。

  • 我不知道“mer”的意思。

  • 使用太多括号,与布尔文字(outpenumerate)相比,风格很差。

所以,使用原始算法修正的代码:

True
相关问题