【Python】辞書型のリストから特定の値を持った要素を検索する処理を高速化する記述法

2023 年 9 月 7 日 by tomokiy

概要

リストの中身が辞書型になっており、その辞書型の値の中で特定の値を持ったデータを検索する場合に高速に検索できる方法を紹介します。

今回は以下の3つの方法を比較します。

  • forループで検索する方法
  • 内包表記+next関数
  • filter関数+next関数

以下の方法では1000万個の辞書型要素を持ったリストのうち、500万個目の要素を検索しています。

forループで検索する方法

もっともオーソドックスですが、最も遅い方法です。

import time
​
list_dict = [{"key":"key"+str(i), "value":"value"+str(i)} for i in range(10000000)]
​
value = None
time_start = time.time()
for i, d in enumerate(list_dict):
    if d["key"] == "key5000000":
        value = d["value"]
        break
time_end = time.time()
​
print("通常のループ",value,time_end-time_start)

内包表記+next関数

最も高速かつ、分かりやすい方法です。

​import time

list_dict = [{"key":"key"+str(i), "value":"value"+str(i)} for i in range(10000000)]
​
time_start = time.time()
value = next((d["value"] for d in list_dict if d["key"] == "key500000"), None)
time_end = time.time()
​
print("ジェネレータ式",value,time_end-time_start)

filter関数+next関数

まあまあ早いですが、ラムダ式を使用するのでとっつきにくいかもしれません。

import time
​
list_dict = [{"key":"key"+str(i), "value":"value"+str(i)} for i in range(10000000)]
​
time_start = time.time()
value = next(filter(lambda d: d["key"] == "key500000", list_dict), None)["value"]
time_end = time.time()
​
print("filter関数",value,time_end-time_start)

比較結果

試行回数forループで検索する方法内包表記+next関数filter関数+next関数
10.48570.02590.0409
20.47880.03590.0399
30.44390.02200.0359
40.43780.02600.0369
50.48770.02300.0379
平均0.46680.02660.0383

やっぱり内包表記だと速いですね~!

最後に

なんでもかんでも内包表記にしとけばいいだろう。。。

タグ:

TrackBack