1. ホーム
  2. python

[解決済み] 辞書のスライス

2022-02-01 23:28:52

質問内容

私は辞書を持っていて、その一部を関数に渡したいのですが、その部分はキーのリスト(またはタプル)により与えられます。以下のような感じです。

# the dictionary
d = {1:2, 3:4, 5:6, 7:8}

# the subset of keys I'm interested in
l = (1,5)

さて、理想を言えば、こんなことができるようになりたい。

>>> d[l]
{1:2, 5:6}

という名前のキーを探してしまうので、うまくいきません。 (1,5) . そして d[1,5] は有効なPythonですらありません(便利そうではありますが)。

これができるのは知っています。

>>> dict([(key, value) for key,value in d.iteritems() if key in l])
{1: 2, 5: 6}

またはこれです。

>>> dict([(key, d[key]) for key in l])

よりコンパクトな ... でも、もっといい方法があるような気がします。私はもっとエレガントな解決策を見逃しているのでしょうか?

(Python 2.7を使用しています。)

どのように解決するのですか?

もしキーが存在し、それがdictにない場合は、キー・エラーが発生することになります。

print({k:d[k] for k in l if k in d})

いくつかのタイミング

 {k:d[k] for k in set(d).intersection(l)}

In [22]: %%timeit                        
l = xrange(100000)
{k:d[k] for k in l}
   ....: 
100 loops, best of 3: 11.5 ms per loop

In [23]: %%timeit                        
l = xrange(100000)
{k:d[k] for k in set(d).intersection(l)}
   ....: 
10 loops, best of 3: 20.4 ms per loop

In [24]: %%timeit                        
l = xrange(100000)
l = set(l)                              
{key: d[key] for key in d.viewkeys() & l}
   ....: 
10 loops, best of 3: 24.7 ms per

In [25]: %%timeit                        

l = xrange(100000)
{k:d[k] for k in l if k in d}
   ....: 
100 loops, best of 3: 17.9 ms per loop

というのは {k:d[k] for k in l} は可読性が低く、エレガントでもありませんし、すべての要素がdにあれば、かなり効率的です。