2012-07-09 20 views
6

Eventuali duplicati:
'has_key()' or 'in'?Efficienza dict.has_key ed inserire dict in Python

In Python, Ci sono due modi di decidere se un key è in una dict :

if dict.has_key(key) e if key in dict

Qualcuno mi dice che il secondo è più lento del primo poiché la parola chiave in rende l'espressione una ripetizione del dett, quindi sarà più lenta dell'alternativa has_key, che apparentemente usa l'hash per prendere la decisione.

Come dubito fortemente della differenza, dal momento che penso che Python sia abbastanza intelligente da tradurre una parola chiave in prima di un dict in modo hash, non riesco a trovare alcuna rivendicazione formale su questo.

Quindi c'è davvero qualche differenza di efficienza tra i due?

Grazie.

risposta

8

Entrambe queste operazioni eseguono la stessa operazione: esaminare la tabella hash implementata nel dict per la chiave. Né itererà l'intero dizionario. Ricordare che for x in dict è diverso da if x in dict. Entrambi usano la parola chiave in, ma sono operazioni diverse.

La parola chiave in diventa una chiamata su dict.__contains__, che Dtc può implementare come preferisce.

Se c'è una differenza nei tempi di queste operazioni, sarà molto piccola e avrà a che fare con la funzione chiamata overhead di has_key.

BTW, la preferenza generale è per key in dict come espressione più chiara dell'intenzione rispetto a dict.has_key(key). Si noti che la velocità non ha nulla a che fare con la preferenza. La leggibilità è più importante della velocità a meno che tu non sappia di essere nel percorso critico.

+2

.... tutto questo, inoltre, 'has_key()' è deprecato e non dovrebbe più essere usato. :) – jonesy

3

D.has_key è effettivamente più lento a causa della chiamata di funzione:

>>> D = dict((x, y) for x, y in zip(range(1000000), range(1000000))) 
>>> from timeit import Timer 
>>> t = Timer("1700 in D", "from __main__ import D") 
>>> t.timeit() 
0.10631704330444336 
>>> t = Timer("D.has_key(1700)", "from __main__ import D") 
>>> t.timeit() 
0.18113207817077637 
+1

Questo è "leggermente"? –

+0

Bene considerando che timeit esegue la dichiarazione un milione di volte, e il numero è in secondi, la differenza di tempo * assoluta * è piuttosto piccola – jterrace

+0

Qualcosa come 80 nanosecondi .. – jterrace

3

has_key non è un'alternativa. È deprecato. Non usarlo (È più lento comunque)