为了详细说明@Helgi 的答案,这里有一个性能更高的递归实现。它更新列表而不是对两个列表求和(这导致每次都创建一个新对象)。
此模式强制您将列表对象作为第三个参数传递。
def split_word(word, num_of_chars, tail):
if len(word) > 0:
tail.append(word[:num_of_chars])
return split_word(word[num_of_chars:], num_of_chars, tail)
return tail
res = split_word('fdjskqmfjqdsklmfjm', 3, [])
这种形式的另一个优点是它允许尾递归优化。它在 Python 中毫无用处,因为它不是一种执行这种优化的语言,但如果你将这段代码翻译成 Erlang 或 Lisp,你将免费获得它。
请记住,在 Python 中,您受到递归堆栈的限制,没有办法摆脱它。这就是为什么递归不是首选方法的原因。
您很可能会使用生成器,使用yield
and itertools
(一个操作生成器的模块)。这是一个可以将任何可迭代对象拆分为块的函数的一个很好的示例:
from itertools import chain, islice
def chunk(seq, chunksize, process=iter):
it = iter(seq)
while True:
yield process(chain([it.next()], islice(it, chunksize - 1)))
现在如果你开始学习 Python 会有点复杂,所以我不指望你现在完全掌握它,但你能看到它并知道它的存在是件好事。您稍后会回来讨论它(我们都这样做了,Python 迭代工具一开始是压倒性的)。
这种方法的好处是:
- 它可以分块任何可迭代的,不仅仅是字符串,还包括列表、字典、元组、流、文件、集合、查询集,你可以命名它......
- 它接受任何长度的迭代,甚至是一个未知长度的迭代(想想这里的字节流)。
- 它占用的内存很少,因为生成器最好的一点是它们会一个接一个地动态生成值,并且在计算下一个结果之前它们不会存储先前的结果。
- 它返回任何性质的块,这意味着您可以拥有 x 个字母的块、x 个项目的列表,甚至是生成 x 个项目的生成器(这是默认设置)。
- 它返回一个生成器,因此可以在其他生成器的流中使用。将数据从一个生成器传输到另一个生成器(bash 风格)是一种出色的 Python 能力。
要获得与您的函数相同的结果,您将执行以下操作:
In [17]: list(chunk('fdjskqmfjqdsklmfjm', 3, ''.join))
Out[17]: ['fdj', 'skq', 'mfj', 'qds', 'klm', 'fjm']