python - Perché dict.get(key) ha funzionato ma non dict[key]?




dictionary (2)

Sto cercando di raggruppare le stringhe binarie di determinati numeri in base al numero di 1 presenti nella stringa.

Questo non funziona:

s = "0 1 3 7 8 9 11 15"
numbers = map(int, s.split())
binaries = [bin(x)[2:].rjust(4, '0') for x in numbers]

one_groups = dict.fromkeys(range(5), [])
for x in binaries:
    one_groups[x.count('1')] += [x]

Il dizionario previsto deve essere one_groups

{0: ['0000'], 
 1: ['0001', '1000'], 
 2: ['0011', '1001'], 
 3: ['0111', '1011'], 
 4: ['1111']}

Ma capisco

{0: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'], 
 1: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'], 
 2: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'], 
 3: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111'], 
 4: ['0000', '0001', '0011', '0111', '1000', '1001', '1011', '1111']}

Finora l'unica cosa che ha funzionato è se uso one_groups[x.count('1')] = one_groups.get(x.count('1')) + [x] invece di one_groups[x.count('1')] += [x]

Ma perché è così? Se ricordo bene, dict[key] dovrebbe restituire il valore di quel dizionario, in modo simile a come funziona dict.get(key) ? Ho visto questa discussione Perché dict.get (chiave) invece di dict [chiave]? ma non ha risposto alla mia domanda per questo caso particolare, poiché so per certo che il programma non è pensato per ottenere KeyError

Ho anche provato one_groups[x.count('1')].append(x) ma neanche questo funziona.


Il problema è la mutabilità:

one_groups = dict.fromkeys(range(5), []) - passa lo stesso elenco di valori a tutte le chiavi . Quindi se cambi un valore, li cambi tutti.

È praticamente lo stesso che dire:

tmp = []
one_groups = dict.fromkeys(range(5), tmp)
del tmp

Se vuoi usare un nuovo elenco, devi farlo in un ciclo - un esplicito for ciclo o in una comprensione dict:

one_groups = {key: [] for key in range(5)}

Questa cosa "eseguirà" [] (che equivale a list() ) per ogni chiave, rendendo così i valori con liste diverse.

Perché funziona? Perché prendi esplicitamente l'elenco corrente, ma + crea un nuovo elenco di risultati. E non importa se si tratta di one_groups[x.count('1')] = one_groups.get(x.count('1')) + [x] o one_groups[x.count('1')] = one_groups[x.count('1')] + [x] - ciò che conta è che ci sia + .

So come tutti dicono a+=b è solo a=a+b , ma l'implementazione potrebbe essere diversa per l'ottimizzazione - in caso di elenchi, += è solo .extend perché sappiamo che vogliamo il nostro risultato nella variabile corrente, quindi creando la nuova lista sarebbe spreco di memoria.


Il problema sta utilizzando one_groups = dict.fromkeys(range(5), [])

(Questo passa lo stesso elenco di valori a tutte le chiavi. Quindi, se si cambia un valore, si cambiano tutti)

Puoi invece one_groups = {i:[] for i in range(5)} : one_groups = {i:[] for i in range(5)}

(Questa cosa "eseguirà" [] (che equivale a list ()) per ogni chiave, rendendo così i valori con liste diverse.)





dictionary