使用递归将字符串拆分为块

2024-10-01 22:33:54 发布

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

我试图把一个任意长度的字符串分成3个字符的块。我知道这个问题以前已经被问过(How do you split a list into evenly sized chunks?),但是这个答案用列表理解解决了这个问题;我试图用递归函数调用来解决这个问题,所以我的问题更多的是关于Python中的递归函数调用。在

我的函数运行良好,直到“基本情况”,即最后一个3个或更少字符的字符串。我得到了TypeError: can only concatenate list (not "NoneType") to list。在

为什么基本情况返回None而不是list?我显式地在基本情况下创建一个名为final_value的列表并返回该列表。我甚至有一个调试print语句,它告诉我基本情况返回值的类型是<class 'list'>。在

我的代码在下面。在

three_char_strings = []

def split3(str):
    if len(str) <= 3:
        final_value = []
        final_value.append(str)
        print('Final value: %s\nFinal value type: %s\n' % (final_value, type(final_value))) #For debugging
        return final_value
    else:
        beginning = str[0:3]
        three_char_strings.append(beginning)
        remaining = str[3:]
        three_char_strings + split3(remaining)

Tags: 字符串列表valuetype情况listfinalthree
2条回答

虽然最初的问题是您的非基本case没有return语句(意味着它隐式返回None),但是了解如何在Python中简化代码也是很有启发性的

def split3(s):
    return [s] if len(s) <= 3 else [s[:3]] + split3(s[3:])

你有两个问题:

  1. 您的只在基本情况下return,因此另一个情况将隐式return None;并且

  2. 在基本情况下,three_char_strings不会发生突变。实际上,还不清楚为什么要实现这个来改变外部列表,因为如果需要再次调用它,这将导致问题。

你应该做些类似的事情:

def split3(str):
    if len(str) <= 3:
        return [str]
    else:
        beginning = str[:3]
        remaining = str[3:]
        return [beginning] + split3(remaining)

它可以满足您的需要,而不依赖于three_char_list列表在作用域内且在调用函数时为空:

^{pr2}$

这种方法的缺点是会创建多个列表。如果您希望每个顶级通话都有一个列表,您可以这样做,例如:

def split3(str, out=None):
    if out is None:
        out = []
    out.append(str[:3])
    if len(str) > 3:
        split3(str[3:], out)
    return out

如果您想知道为什么out=None,请参见"Least Astonishment" and the Mutable Default Argument。在

相关问题 更多 >

    热门问题