質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

866閲覧

複数の特定のkeyを取り除いた辞書を作る効率的な方法

gottadiveintopy

総合スコア736

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2021/05/07 05:08

編集2021/05/07 08:13

題の通りの事をする関数を以下のように二種類作ってみたところ

python

1unnecessary_keys = ('s', 'd', 't', 'step', 'duration', 'transition', ) 2 3def method_1(d): 4 d = d.copy() 5 for key in unnecessary_keys: 6 d.pop(key, None) 7 return d 8 9def method_2(d): 10 return { 11 key: value for key, value in d.items() 12 if key not in unnecessary_keys 13 } 14 15sample_dict = {'x': 100, 'y': 200, 'd': 10, 't': 'in_cubic', } 16assert method_1(sample_dict) == {'x': 100, 'y': 200, } 17assert method_2(sample_dict) == {'x': 100, 'y': 200, } 18 19from timeit import timeit 20print(timeit(lambda: method_1(sample_dict))) # => 5.955087270995136 21print(timeit(lambda: method_2(sample_dict))) # => 7.697444974000973

内包表記を使っていないmethod_1()の方が速いという結果になりました。これよりも速い方法を知ってませんか?

補足

  • 与えられる辞書に含まれるunnecessary_keys以外のkeyは一つか二つである事が多いです。(つまりsample_dictのような物が多い)
  • unnecessary_keysは上に書いた内容で常に固定されています。 除きたいkeyは上に書いた6つで固定されています。

環境

CPython 3.7.1

追記

得られた回答を元に以下の6つも比較対象に加えた結果

unnecessary_keys = ('s', 'd', 't', 'step', 'duration', 'transition', ) intersection = set(unnecessary_keys).intersection def method_3a(d): '''ppaulさんのmethod_3に少し手を加えた物''' d = d.copy() for key in intersection(d): d.__delitem__(key) return d def method_3b(d): '''method_3aの'd.__delitem__'をloopの外に出した物''' d = d.copy() delitem = d.__delitem__ for key in intersection(d): delitem(key) return d def method_4a(d): '''ppaulさんのmethod_4''' d = d.copy() for key in unnecessary_keys: if key in d: d.__delitem__(key) return d def method_4b(d): '''method_4aの'd.__delitem__'をloopの外に出した物''' d = d.copy() delitem = d.__delitem__ for key in unnecessary_keys: if key in d: delitem(key) return d def method_5(d): '''quickquipさんの方法''' d = d.copy() for key in unnecessary_keys: if key in d: del d[key] return d def method_6(d): '''quickquipさんの方法''' d = d.copy() for key in intersection(d): del d[key] return d
1 : 6.086940804998449 2 : 7.495010836995789 3a: 5.200945402000798 3b: 5.059846481999557 4a: 5.46594832399569 4b: 5.468696205003653 5 : 5.198188450005546 6 : 4.907909608999034

以下の順となりました。code全体

  1. method_6
  2. method_3bmethod_5 (順位は不安定。method_3bの方が速いことが多い)
  3. method_3a
  4. method_4amethod_4b (順位は不安定)
  5. method_1
  6. method_2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

python

1def method_straight(d): 2 d = d.copy() 3 for key in unnecessary_keys: 4 if key in d: 5 del d[key] 6 return d

が結局一番速いんじゃないでしょうか。


intersectionが(こちらの環境よりも)利くみたいなので

python

1def method_6(d): 2 d = d.copy() 3 for key in intersection(d): 4 del d[key] 5 return d

も試していいかと。

投稿2021/05/07 06:26

編集2021/05/07 07:00
quickquip

総合スコア11235

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2021/05/07 06:36

macとLinuxの3.7.xではこれが速かったです。 OS,CPUアーキテクチャ,CPythonのビルドが違えば結果が違う可能性もありそう。
gottadiveintopy

2021/05/07 06:46

ありがとうございます。追記にあるmethod_3bと並んで一番速いという結果になりました。
gottadiveintopy

2021/05/07 06:53 編集

if key in d: del d[key] の方が d.pop(key, None) より速いのは知らなかったですね、勉強になりました。
quickquip

2021/05/07 06:55

Python3で時間が掛かるのはメソッド呼び出しという印象です。 意外に結果が違うのでOSが知りたいように思いました……。
gottadiveintopy

2021/05/07 07:19 編集

あ〜 method_6()が一番速くなりました。ただPyPIで公開しているlibraryのcodeなので私の環境に最適化されすぎるはまずいかもです。
quickquip

2021/05/07 07:46

「unnecessary_keys 固定」が前提ならintersectionを使わず素直に書くのが意図も伝わっていい気がします
guest

0

可能性があるのは、こんなところでしょうか。

python

1def method_3(d): 2 d = d.copy() 3 for key in set(unnecessary_keys).intersection(a): 4 d.__delitem__(key) 5 return d 6 7def method_4(d): 8 d = d.copy() 9 for key in unnecessary_keys: 10 if key in d: 11 d.__delitem__(key) 12 return d

測定していないので、はかってみてください。

投稿2021/05/07 05:42

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gottadiveintopy

2021/05/07 06:27

ありがとうございます。どちらの方法も私の物より速くなりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問