Tech

Pythonで辞書dictを分割する方法 [任意の大きさに切り分ける]

2021年4月19日

Pythonにはリストと辞書(連想配列に相当)など、繰り返し可能な配列を扱うための、便利で強力な仕組みが備わっています。

この記事では「辞書を分割する」方法を解説します。

リストを分割するのはよくあることですが、辞書を分割しようとするのはあまりやらないはず。

かなりニッチではありますが、忘れたときのためにメモを残しておきます。

 

辞書dictを任意の大きさに分割する

itertools.islice 関数を使います。

itertoolsモジュールは標準ライブラリなので、インストールは不要(import は必要)。

 

テストデータとして、以下のようなdata を用意しています。含まれているキーは合計10個(0〜9)。

data = { i:i**2 for i in range(10) }

#{
#  0: 0,
#  1: 1,
#  2: 4,
#  3: 9,
#  4: 16,
#  5: 25,
#  6: 36,
#  7: 49,
#  8: 64,
#  9: 81
#}

 

結論からいえば、以下のようなジェネレータを作ってあげます。

 

from itertools import islice



def dict_chunks(data, size):

    it = iter(data)

    for i in range(0, len(data), size):

        yield {k:data[k] for k in islice(it, size)}

 

chunks = dict_chunks(data, size=3)

 

上の例では、chunks 変数に、3要素ごとに分割後の辞書(ジェネレータ)が入ります。

あとは作られたジェネレータを使って、以下のようにfor文をまわしたり、もしくは1つずつnext()することで分割された要素を得られます。

 

count = 0

for c in chunks:

    print(f"chunk {count}: {c.keys()}")

    count += 1
 
# chunk 0: dict_keys([0, 1, 2])
# chunk 1: dict_keys([3, 4, 5])
# chunk 2: dict_keys([6, 7, 8])
# chunk 3: dict_keys([9])

 

上記dict_chunks()では、まず辞書をイテレータに変換し、itertools.isliceを使って一定範囲を抽出。

それを配列に戻して、yieldすることで、擬似的に辞書を分割しています。

 

公式ドキュメントより

itertools.islice(iterablestop)

itertools.islice(iterablestartstop[, step])

iterable から要素を選択して返すイテレータを作成します。 start が0でない場合、iterable の要素は start に達するまでスキップされます。その後、 要素が順に返されます。

list(リスト)では、data[:10]などのように範囲を指定して要素を取り出すことができますが、これと同じようなことを辞書でもできるのがislice()のいいところ。

例えば、辞書をキー順にソートし、n番目のアイテムを取り出すなんて操作もできてしまいます(そんな機会はないと思いますが)。

data = { i:i**2 for i in range(10) }
it = iter(data)

# 6番目から最後まで抽出
chunk = next(islice(it, 6, None)) 
pprint.pprint(chunk)  # 6

 

リストの分割

辞書ではなく、リストの分割についても再確認しておきましょう。

リストの分割はNumpyのarray_split()を使うのが、かんたんで手っ取り早いです。

 

このようなリストがあるときに

list_data = [ i for i in range(10)]

print(list_data)

#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

こうすると、3つに分割できます。

import numpy as np


chunked_list = list(np.array_split(list_data, 3))
 

pprint.pprint(chunked_list, width=40)
 
# [array([0, 1, 2, 3]),
#  array([4, 5, 6]),
#  array([7, 8, 9])]

 

 

まとめ

今回は1つの辞書(dict変数)を複数に分割する方法を解説しました。

巨大な辞書を扱っていて、他と通信する必要があるときなどに活用できるかもしれません。

 

参考文献

https://qiita.com/shihono/items/1613f7c6c1b096256bd3

  • この記事を書いた人

nextpenguin

システム開発・プログラミングのしごとやっています。甘味とコーヒーは生命線。日常での学びを記事にしています。

-Tech
-

© 2021 スターレイヴ