2012-12-04 11 views
6

Ho un dizionario molto grande, forse circa 10,000 keys/values e voglio modificare simultaneamente tutti i valori su 0. Sono consapevole che posso scorrere e impostare tutti i valori su 0 ma ci vorrà per sempre. È comunque possibile che sia possibile contemporaneamente impostare tutti i valori su 0?Sostituendo contemporaneamente tutti i valori di un dizionario a zero python

metodo Looping, molto lento:

#example dictionary 
a = {'a': 1, 'c': 1, 'b': 1, 'e': 1, 'd': 1, 'g': 1, 'f': 1, 'i': 1, 'h': 1, 'k': 1, 
'j': 1, 'm': 1, 'l': 1, 'o': 1, 'n': 1, 'q': 1, 'p': 1, 's': 1, 'r': 1, 'u': 1, 
't': 1, 'w': 1, 'v': 1, 'y': 1, 'x': 1, 'z': 1} 
for key.value in a.items(): 
    a[key] = 0 

uscita:

{'a': 0, 'c': 0, 'b': 0, 'e': 0, 'd': 0, 'g': 0, 'f': 0, 'i': 0, 'h': 0, 'k': 0, 
'j': 0, 'm': 0, 'l': 0, 'o': 0, 'n': 0, 'q': 0, 'p': 0, 's': 0, 'r': 0, 'u': 0, 
't': 0, 'w': 0, 'v': 0, 'y': 0, 'x': 0, 'z': 0} 
+0

Avete profilato il codice e trovato che questo è il fattore limitante ? Un dizionario con articoli 10k non è molto grande. –

+0

Non è tanto la dimensione quanto quante volte ho intenzione di scorrere i dizionari. L'ho programmato per scorrere quasi ogni secondo e inoltre, non ho uno ma più dizionari. – enginefree

+0

È possibile impostare contemporaneamente tutti i valori su 0 se tutti i valori si trovano in un blocco di memoria continua. Non penso che tu possa farlo con il dict incorporato ... a meno che tu non crei il tuo dict implementando la propria struttura dati in C. –

risposta

20

Volete dict.fromkeys():

a = dict.fromkeys(a, 0) 
+0

è più veloce del ciclo? e credo che occorrerà il doppio della memoria durante l'esecuzione, poiché sta creando una copia separata, corretta? – ernie

+1

Sorprendentemente, il looping è più veloce, il tuo metodo, '10000000 loop, meglio di 3: 0.0226 usec per loop', looping' 10000000 loop, meglio di 3: 0.0224 usec per loop' – enginefree

+1

@enginefree grazie per la profilazione; Immagino che i due dovrebbero essere simili dal momento che sia il loop originale che i tasti di scelta probabilmente usano gli iteratori. Penso che l'idea di kreativitea di memorizzare una copia vuota abbia più senso. – ernie

5

Grazie @akaRem per il suo commento :)

a = dict.fromkeys(a.iterkeys(), 0) 
+3

poiché non è necessario copiare tutte le chiavi, sarà meglio usare 'iterkeys()' – akaRem

0

Se si conosce il tipo tuoi valori dict bisogno di essere, si potrebbe in questo modo:

  1. negozio i valori dict in un oggetto array.array. Questo utilizza un blocco di memoria continuo.
  2. dict, invece di memorizzare i valori effettivi avrebbe memorizzare l'indice di matrice in cui il valore effettivo possono essere trovate
  3. reinizializzare la matrice con una stringa binaria contigui di zeri

NON HA testare le prestazioni , ma dovrebbe essere più veloce ...


import array 

class FastResetDict(object): 

    def __init__(self, value_type): 
     self._key_to_index = {} 
     self._value_type = value_type 
     self._values = array.array(value_type) 

    def __getitem__(self, key): 
     return self._values[self._key_to_index[key]] 

    def __setitem__(self, key, value): 
     self._values.append(value) 
     self._key_to_index[key] = len(self._values) - 1 

    def reset_content_to_zero(self): 
     zero_string = '\x00' * self._values.itemsize * len(self._values) 
     self._values = array.array(self._value_type, zero_string) 



fast_reset_dict = FastResetDict('i') 
fast_reset_dict['a'] = 103 
fast_reset_dict['b'] = -99 

print fast_reset_dict['a'], fast_reset_dict['b'] 
fast_reset_dict.reset_content_to_zero() 
print fast_reset_dict['a'], fast_reset_dict['b'] 
1

Attenzione, se l'ordine delle vostre chiavi importa la soluzione potrebbe non essere adatto come sembra riordinare.

Per evitare che questo succeda lista uso di comprensione:

aDictionary = { x:0 for x in aDictionary} 

Nota: E 'solo 2.7.x e 2.x esclusiva

Problemi correlati