@Helgiの回答を詳しく説明するために、よりパフォーマンスの高い再帰的な実装を次に示します。2 つのリストを合計するのではなく、リストを更新します (その結果、毎回新しいオブジェクトが作成されます)。
このパターンでは、リスト オブジェクトを 3 番目のパラメーターとして渡す必要があります。
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, [])
この形式のもう 1 つの利点は、末尾再帰の最適化が可能になることです。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 反復ツールは最初は圧倒されます)。
このアプローチの利点は次のとおりです。
- 文字列だけでなく、リスト、辞書、タプル、ストリーム、ファイル、セット、クエリセットなど、あらゆるイテラブルをチャンクできます...
- 任意の長さの iterable を受け入れ、長さが不明なものも受け入れます (ここではバイト ストリームを考えてください)。
- ジェネレーターの最も良い点は、その場で値を 1 つずつ生成し、次の計算の前に前の結果を保存しないことであるため、ほとんどメモリを消費しません。
- 任意の性質のチャンクを返します。つまり、x 個の文字のチャンク、x 個のアイテムのリスト、さらには x 個のアイテムを吐き出すジェネレーター (これがデフォルトです) を持つことができます。
- ジェネレーターを返すため、他のジェネレーターのフローで使用できます。1 つのジェネレーターから別のジェネレーターへのデータのパイプ処理 (bash スタイル) は、Python の優れた機能です。
関数と同じ結果を得るには、次のようにします。
In [17]: list(chunk('fdjskqmfjqdsklmfjm', 3, ''.join))
Out[17]: ['fdj', 'skq', 'mfj', 'qds', 'klm', 'fjm']