In Think Python l'autore introduce defaultdict . Quello che segue è un estratto dal libro riguardante defaultdict :
If you are making a dictionary of lists, you can often write simpler code using defaultdict. In my solution to Exercise 12-2, which you can get from http://thinkpython2.com/code/anagram_sets.py, I make a dictionary that maps from a sorted string of letters to the list of words that can be spelled with those letters. For example, 'opst' maps to the list ['opts', 'post', 'pots', 'spot', 'stop', 'tops']. Here’s the original code:
def all_anagrams(filename): d = {} for line in open(filename): word = line.strip().lower() t = signature(word) if t not in d: d[t] = [word] else: d[t].append(word) return d
This can be simplified using setdefault, which you might have used in Exercise 11-2:
def all_anagrams(filename): d = {} for line in open(filename): word = line.strip().lower() t = signature(word) d.setdefault(t, []).append(word) return d
This solution has the drawback that it makes a new list every time, regardless of whether it is needed. For lists, that’s no big deal, but if the factory function is complicated, it might be. We can avoid this problem and simplify the code using a defaultdict:
def all_anagrams(filename): d = defaultdict(list) for line in open(filename): word = line.strip().lower() t = signature(word) d[t].append(word) return d
Ecco la definizione della funzione signature
:
def signature(s):
"""Returns the signature of this string.
Signature is a string that contains all of the letters in order.
s: string
"""
# TODO: rewrite using sorted()
t = list(s)
t.sort()
t = ''.join(t)
return t
Quello che ho capito per quanto riguarda la seconda soluzione è che setdefault
controlla se t
(la firma della parola) esiste come una chiave, altrimenti, la imposta come una chiave e imposta una lista vuota come valore, quindi append
aggiunge la parola ad esso. Se t
esiste, setdefault
restituisce il suo valore (una lista con almeno un elemento, che è una stringa che rappresenta una parola), e append
aggiunge la parola a questo elenco.
Quello che ho capito per quanto riguarda la terza soluzione è che d
, che rappresenta un defaultdict , rende t
una chiave e imposta una lista vuota come valore (se t
non è già esiste come chiave), quindi la parola viene aggiunta all'elenco. Se t
esiste già, viene restituito il suo valore (l'elenco) e al quale viene aggiunta la parola.
Qual è la differenza tra la seconda e la terza soluzione? I Cosa significa che il codice nella seconda soluzione crea ogni volta un nuovo elenco, indipendentemente dal fatto che sia necessario? In che modo setdefault
è responsabile per questo? In che modo utilizzare defaultdict ci fa evitare questo problema? In che modo la seconda e la terza soluzione sono diverse?