Mam program w języku Python, który często współpracuje ze słownikami. Muszę robić kopie słowników tysiące razy. Potrzebuję kopii kluczy i związanej z nimi zawartości. Kopia zostanie poddana edycji i nie może być powiązana z oryginałem (np. Zmiany w kopii nie mogą wpływać na oryginał).
Klucze to ciągi, wartości to liczby całkowite (0/1).
Obecnie używam prostego sposobu:
newDict = oldDict.copy()
Profilowanie mojego kodu pokazuje, że operacja kopiowania zajmuje większość czasu.
Czy istnieją szybsze alternatywy dla tej dict.copy()
metody? Co byłoby najszybsze?
python
performance
dictionary
copy
Joern
źródło
źródło
bool
byłby lepszym wyborem niżint
?bool
w Pythonieint
.bool
typ jest w rzeczywistości podklasą (podtypem?)int
Typu.Odpowiedzi:
Patrząc na źródło C dla
dict
operacji Pythona , widać, że wykonują one dość naiwną (ale wydajną) kopię. Zasadniczo sprowadza się do wezwania doPyDict_Merge
:To wykonuje szybkie sprawdzenie rzeczy, takich jak to, czy są tym samym obiektem i czy mają w sobie obiekty. Następnie wykonuje jednorazową hojną zmianę rozmiaru / alokację do docelowego dyktu, a następnie kopiuje elementy jeden po drugim. Nie widzę, żebyś był dużo szybszy niż wbudowany
copy()
.źródło
Jak mówisz, najwyraźniej dict.copy jest szybsze.
[utdmr@utdmr-arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = d.copy()" 1000000 loops, best of 3: 0.238 usec per loop [utdmr@utdmr-arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = dict(d)" 1000000 loops, best of 3: 0.621 usec per loop [utdmr@utdmr-arch ~]$ python -m timeit -s "from copy import copy; d={1:1, 2:2, 3:3}" "new = copy(d)" 1000000 loops, best of 3: 1.58 usec per loop
źródło
timeit
„s-s
argumentu:python -m timeit -s "from copy import copy" "new = copy({1:1, 2:2, 3:3})"
. Kiedy już to zrobisz, wyciągnij również dyktando (dla wszystkich przykładów).Czy możesz podać przykładowy kod, abym mógł zobaczyć, jak używasz funkcji copy () i w jakim kontekście?
Możesz użyć
Ale nie sądzę, żeby to było szybsze.
źródło
Zdaję sobie sprawę, że to stary wątek, ale jest to wysoki wynik w wyszukiwarkach dla hasła „dict copy python” i najwyższy wynik dla „wydajności kopiowania dyktowania” i uważam, że to ma znaczenie.
Od wersji Python 3.7
newDict = oldDict.copy()
jest nawet 5,5x szybsza niż poprzednio. Warto zauważyć, że w tej chwilinewDict = dict(oldDict)
wydaje się , że nie ma takiego wzrostu wydajności.Jest trochę więcej informacji tutaj .
źródło
W zależności od rzeczy, które pozostawisz spekulacjom, możesz chcieć zawinąć oryginalny słownik i zrobić coś w rodzaju kopiowania przy zapisie.
„Kopia” jest wówczas słownikiem, który wyszukuje rzeczy w słowniku „nadrzędnym”, jeśli nie zawiera już klucza --- ale umieszcza modyfikacje w sobie.
Zakłada się, że nie będziesz modyfikować oryginału i że dodatkowe wyszukiwania nie będą kosztować więcej.
źródło
Pomiary zależą jednak od rozmiaru słownika. Dla 10000 wpisów copy (d) i d.copy () są prawie takie same.
a = {b: b for b in range(10000)} In [5]: %timeit copy(a) 10000 loops, best of 3: 186 µs per loop In [6]: %timeit deepcopy(a) 100 loops, best of 3: 14.1 ms per loop In [7]: %timeit a.copy() 1000 loops, best of 3: 180 µs per loop
źródło