Klasa posiada konstruktor, który przyjmuje jeden parametr:
class C(object):
def __init__(self, v):
self.v = v
...
Gdzieś w kodzie przydatne jest, aby wartości w dyktandzie znały swoje klucze.
Chcę użyć defaultdict z kluczem przekazanym do wartości domyślnych noworodka:
d = defaultdict(lambda : C(here_i_wish_the_key_to_be))
Jakieś sugestie?
python
dictionary
defaultdict
Benjamin Nitlehoo
źródło
źródło
defaultdict
jest__missing__()
metoda może być pominięte (jak to można w dowolnej podklasy wbudowanych wdict
klasie od wersji 2.5).Nie, nie ma.
defaultdict
Realizacja nie może być skonfigurowany do przekazywania brakujekey
dodefault_factory
out-of-the-box. Jedyną opcją jest zaimplementowanie własnejdefaultdict
podklasy, zgodnie z sugestią @JochenRitzel powyżej.Ale to nie jest „sprytne” ani prawie tak czyste, jak byłoby to standardowe rozwiązanie biblioteczne (gdyby istniało). Zatem odpowiedź na twoje zwięzłe pytanie, tak / nie, brzmi wyraźnie „nie”.
Szkoda, że w standardowej bibliotece brakuje tak często potrzebnego narzędzia.
źródło
Myślę, że wcale nie potrzebujesz
defaultdict
tutaj. Dlaczego po prostu nie użyćdict.setdefault
metody?>>> d = {} >>> d.setdefault('p', C('p')).v 'p'
To oczywiście spowodowałoby wiele przypadków
C
. Myślę, że w przypadku problemu wystarczy prostsze podejście:>>> d = {} >>> if 'e' not in d: d['e'] = C('e')
Byłoby to szybsze niż ta
defaultdict
lub jakakolwiek inna alternatywa, o ile widzę.ETA w odniesieniu do szybkości
in
testu vs. stosowanie klauzuli try-except:>>> def g(): d = {} if 'a' in d: return d['a'] >>> timeit.timeit(g) 0.19638929363557622 >>> def f(): d = {} try: return d['a'] except KeyError: return >>> timeit.timeit(f) 0.6167065411074759 >>> def k(): d = {'a': 2} if 'a' in d: return d['a'] >>> timeit.timeit(k) 0.30074866358404506 >>> def p(): d = {'a': 2} try: return d['a'] except KeyError: return >>> timeit.timeit(p) 0.28588609450770264
źródło
d[key]
aby wrócić,d[key] = C(key)
jeślikey not in d
. Ale twoje rozwiązanie wymaga od niego, aby faktycznie działał i ustawiałd[key]
z wyprzedzeniem? Skąd miałby wiedzieć, czegokey
będzie potrzebował?Oto działający przykład słownika, który automatycznie dodaje wartość. Zadanie demonstracyjne polegające na znajdowaniu zduplikowanych plików w / usr / include. Zauważ, że słownik PathDict dostosowywania wymaga tylko czterech wierszy:
class FullPaths: def __init__(self,filename): self.filename = filename self.paths = set() def record_path(self,path): self.paths.add(path) class PathDict(dict): def __missing__(self, key): ret = self[key] = FullPaths(key) return ret if __name__ == "__main__": pathdict = PathDict() for root, _, files in os.walk('/usr/include'): for f in files: path = os.path.join(root,f) pathdict[f].record_path(path) for fullpath in pathdict.values(): if len(fullpath.paths) > 1: print("{} located in {}".format(fullpath.filename,','.join(fullpath.paths)))
źródło