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

时间:2015-02-17 15:56:37

标签: python string python-3.x

我正在尝试将任意长度的字符串拆分为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)

2 个答案:

答案 0 :(得分:3)

你有两个问题:

  1. 基本情况下 return,因此另一种情况将隐含return None;以及

  2. 您不会在基本情况下改变three_char_strings。事实上,目前尚不清楚为什么要实现这一点来改变所有的外部列表,因为如果你需要再次调用它会导致问题。

  3. 你可能应该做的事情如下:

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

    当你调用这个函数时,你想要的是什么,没有依赖three_char_list列表在范围内并且为空:

    >>> split3('abcdefghijklmnopqrstuvwxyz')
    ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz']
    

    这种方法的缺点是它创建了几个列表。如果你想要每个顶级呼叫一个列表,你可以做例如:

    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

答案 1 :(得分:2)

虽然最初的问题是您的非基本情况没有return声明(意味着它隐式返回None),但看看如何代码可以在Python中简化

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