Python 3.12では、標準ライブラリのitertools
にbatched
という関数が追加されました。
batched
は、イテラブルをN個ずつまとめる関数です。
以下は、batched
のヘルプからの抜粋です。7文字を3文字ずつにまとめるサンプルになります。
>>> for batch in batched('ABCDEFG', 3): ... print(batch) ... ('A', 'B', 'C') ('D', 'E', 'F') ('G',)
早速、次のような課題で使ってみましょう。
課題
A社では、明日の内定式で、内定者10人のグループワークを行います。
グループワークはテーブルごとにします。このテーブルは4人がけなので3グループにわかれます。
グループがランダムになるように割り振ってください。
Pythonで解いてみよう
最初に、10人の内定者のリストを用意しましょう。
names = ['田中', '小林', '佐藤', '松田', '川村', '岡本', '高橋', '坂井', '山田', '井上']
このリストからランダムに4人選ぶことを繰り返すとよさそうです。
最初に、ランダムに並び替えましょう。ランダムに並び替えをするには、random
モジュールのshuffle
が使えます。
import random random.shuffle(names) print(names)
出力
['小林', '岡本', '松田', '高橋', '川村', '井上', '田中', '山田', '佐藤', '坂井']
names
の並びがランダムになりました。
続いて、グループごとに出力しましょう。先頭から4人ずつ取得するには、下記のようにスライスを使います。
print(names[0:4]) # グループ1 print(names[4:8]) # グループ2 print(names[8:10]) # グループ3
出力
['小林', '岡本', '松田', '高橋'] ['川村', '井上', '田中', '山田'] ['佐藤', '坂井']
これで、グループごとに出力できました。しかし、このような書き方は、グループが増えると大変です。forを使って書き直してみましょう。
for i in range(0, 10, 4): print(names[i:i+4])
出力
['小林', '岡本', '松田', '高橋'] ['川村', '井上', '田中', '山田'] ['佐藤', '坂井']
書き換えた結果も同じ出力になりました。
最後のグループは、names[8:12]
になっていますが、はみ出てた分は無視されるので問題ありません。
これでできたのですが、コードがちょっとわかりにくいです。時間が経つと何をやっているかわからなくなりそうです。
実は、Python 3.12で追加されたitertools
のbatched
を使うと、もっとわかりやすくなります。
やってみましょう。
from itertools import batched for group in batched(names, 4): print(group)
出力
('小林', '岡本', '松田', '高橋') ('川村', '井上', '田中', '山田') ('佐藤', '坂井')
リストがタプルになっていますが、中身は同じになっています。
batched
は、指定の数だけ集めてグループを作る関数です。第2引数が指定の数です。
batched(names, 4)
は「names
から4つずつ集めている」ということがわかりやすくなっています。
itertools
は標準ライブラリなので、準備も不要で使いやすいです。
batched
と同じことは、サードパーティ製ライブラリのmore-itertools
のchunked
を使ってもできます。
書き方は、ほぼ同じですね。
from more_itertools import chunked for group in chunked(names, 4): print(group)
出力
['小林', '岡本', '松田', '高橋'] ['川村', '井上', '田中', '山田'] ['佐藤', '坂井']
この場合は、次のようにmore-itertools
をインストールすれば、Python 3.11以前でも使えます。
pip install more-itertools
chunked
に似た関数に、chunked_even
というものがあります。
こちらは、グループ内の数の差を最小にするものです。使い方はchunked
と同じです。
from more_itertools import chunked_even for group in chunked_even(names, 4): print(group)
出力
['小林', '岡本', '松田', '高橋'] ['川村', '井上', '田中'] ['山田', '佐藤', '坂井']
グループの最小人数が2人から3人になりました。グループワークをするには、こちらの方がよさそうですね。
itertools.batched
やmore-itertools.chunked
などについて詳しく知りたい方は、下記も参照してみてください。