2015-09-20 5 views
5

私は、これは安全であると思う:キーが辞書にあるかどうかをチェックしていて、同じ "if"の値でその値を取得していますか?

if key in test_dict: 
    if test_dict[key] == 'spam': 
     print('Spam detected!') 

が、これは安全なのですか?

if key in test_dict and test_dict[key] == 'spam': 
    print('Spam detected!') 

条件チェックがPythonで怠惰なので同じことをする必要があります。最初の条件が既に満たされていないため、値を取得しようとしません(およびdictにそのようなキーがないため例外を発生させます)。しかし、私は怠惰に頼って、私のプログラムで2番目の例を使うことができますか?

+3

はい、両方のスニペットは同等で安全です。 –

答えて

13

はい、それは、偽の最初の式の結果ならば、Pythonが短絡だろう、安全であることif状態の2番目の式は評価されません。

しかし、条件を実行するより良い方法は、キーが辞書に存在しない場合Noneを返す.get()を使用することです。例 -

if test_dict.get(key) == 'spam': 
    print('Spam detected!') 
+4

それは同等ではありません - スパムキーは値 'なし'を持つかもしれません。 –

+1

この場合も同様に、条件は満たされません。 '' None''はスパムと等しくありません。 –

+0

@AnandSKumarだから、それがうまくいかない状況は、私がNoneを探すときだけです。 –

3

and test_dict[key] == 'spam':if key in test_dictTrueの場合にのみ評価されます。ネストした場合の最初のコードとまったく同じように動作します。

andを使用する場合、式の両辺はTrueである必要があります。key in test_dictがFalseを返した場合、コードは短絡します。

あなたandアプローチを使用すると、式の左側がFalseの場合は特に、実際に最も効率的である:

In [13]: d = {k:k for k in range(10000)} 
In [14]: timeit 99999 in d and d[100] == "foo" 
10000000 loops, best of 3: 48.2 ns per loop 

In [15]: timeit d.get(9000) == "foo" 
10000000 loops, best of 3: 155 ns per loop 
In [16]: timeit 100 in d and d[100] == "foo 
10000000 loops, best of 3: 119 ns per loo  
In [17]: timeit d.get(100) == "foo" 
10000000 loops, best of 3: 141 ns per loop 
+0

もっと効率的ですが、単純に 'd [100] ==" foo "'ですが、丸め以外は試してみてください。ほとんどのキーが辞書にない場合を除きます。 – strubbly

関連する問題