Zastanawiałem się więc, jak najlepiej utworzyć listę pustych list:
[[],[],[]...]
Ze względu na sposób, w jaki Python działa z listami w pamięci, to nie działa:
[[]]*n
To tworzy, [[],[],...]
ale każdy element jest tą samą listą:
d = [[]]*n
d[0].append(1)
#[[1],[1],...]
Coś w rodzaju rozumienia listy działa:
d = [[] for x in xrange(0,n)]
Ale to używa maszyny wirtualnej Python do zapętlenia. Czy istnieje sposób na użycie implikowanej pętli (wykorzystując ją napisaną w C)?
d = []
map(lambda n: d.append([]),xrange(0,10))
To jest faktycznie wolniejsze. :(
d = [[] for x in xrange(0,n)]
. Musisz albo wykonać pętlę jawnie w Pythonie, albo wielokrotnie wywoływać funkcję / lambdę Pythona (co powinno być wolniejsze). Ale wciąż mam nadzieję, że ktoś opublikuje coś, co pokazuje, że się mylę :).timeit
Czego się nauczyłeś , mierząc te wartości ?map(lambda x: [], xrange(n))
jest to wolniejsze niż rozumienie listy.Odpowiedzi:
Prawdopodobnie jedyny sposób, który jest nieznacznie szybszy niż
jest
Nie musi tworzyć nowego
int
obiektu w każdej iteracji i jest około 15% szybszy na moim komputerze.Edycja : używając NumPy, możesz uniknąć pętli Pythona używając
ale w rzeczywistości jest to 2,5 razy wolniejsze niż rozumienie listy.
źródło
map(lambda x:[], repeat(None,n))
?Listy składane są faktycznie implementowane wydajniej niż jawne zapętlanie (zobacz dane
dis
wyjściowe, na przykład funkcje ), amap
sposób musi wywoływać nieprzejrzysty wywoływalny obiekt w każdej iteracji, co wiąże się ze znacznym narzutem.Niezależnie od tego,
[[] for _dummy in xrange(n)]
jest to właściwy sposób i żadna z drobnych (jeśli w ogóle istnieją) różnic prędkości między różnymi innymi sposobami nie powinna mieć znaczenia. O ile oczywiście nie spędzasz na tym większości czasu - ale w takim przypadku powinieneś zamiast tego popracować nad algorytmami. Jak często tworzysz te listy?źródło
_
jako nazwę zmiennej! W przeciwnym razie miła odpowiedź :)i
, szukałbym , gdzie jest używany). Jedyną pułapką byłoby to, że przesłaniałby_
ostatni wynik w REPL ... i tak jest tylko w przypadku 2.x, w którym wyciekają wyrażenia listy._
w interaktywnym interpretatorze, jest również w konflikcie ze wspólnym aliasem gettext. Jeśli chcesz wyjaśnić, że zmienna jest zmienną fikcyjną, nazwij jądummy
, a nie_
.Oto dwie metody, jedna słodka i prosta (i koncepcyjna), druga bardziej formalna i może być rozszerzona w różnych sytuacjach po przeczytaniu zbioru danych.
Metoda 1: koncepcyjne
Metoda 2: Formalna i rozszerzalna
Kolejny elegancki sposób przechowywania listy jako listy list różnych numerów - które odczytuje z pliku. (W tym pliku znajduje się pociąg zestawu danych) Train to zestaw danych zawierający powiedzmy 50 wierszy i 20 kolumn. to znaczy. Train [0] daje mi pierwszy wiersz pliku csv, train [1] drugi wiersz i tak dalej. Interesuje mnie oddzielenie zbioru danych z 50 wierszami jako jedną listę, z wyjątkiem kolumny 0, która jest tutaj moją wyjaśnioną zmienną, więc należy ją usunąć z oryginalnego zestawu danych pociągu, a następnie przeskalować listę po liście w górę - tj. Lista listy . Oto kod, który to robi.
Zauważ, że czytam od „1” w pętli wewnętrznej, ponieważ interesują mnie tylko zmienne objaśniające. I ponownie inicjalizuję X1 = [] w drugiej pętli, w przeciwnym razie X2.append ([0: (len (train [0]) - 1)]) przepisze X1 w kółko - poza tym bardziej wydajna pamięć.
źródło
Aby utworzyć listę i listę list, użyj poniższej składni
to utworzy listę 1-d i aby ją zainicjalizować, umieść numer w [[liczba] i ustaw długość listy wstawionej długości w przedziale (długość)
spowoduje to zainicjowanie listy list o wymiarze 10 * 3 i wartości 0
źródło
Więc zrobiłem kilka porównań prędkości, aby uzyskać najszybszą drogę. Rozumienie listy jest rzeczywiście bardzo szybkie. Jedynym sposobem na zbliżenie się jest uniknięcie wykonania kodu bajtowego podczas tworzenia listy. Moja pierwsza próba była następująca, która wydawałaby się w zasadzie szybsza:
(oczywiście tworzy listę o długości 2 ** n) Konstrukcja ta jest dwa razy wolniejsza niż rozumienie list według timeit, zarówno dla krótkich, jak i długich (milion) list.
Moją drugą próbą było użycie starmap do wywołania konstruktora listy za mnie.Istnieje jedna konstrukcja, która wydaje się uruchamiać konstruktor listy z maksymalną prędkością, ale nadal jest wolniejsza, ale tylko o niewielką wartość:
Co ciekawe, czas wykonania sugeruje, że to ostatnie wywołanie listy spowalnia rozwiązanie Starmap, ponieważ jego czas wykonania jest prawie dokładnie równy szybkości:
Moja trzecia próba nastąpiła, gdy zdałem sobie sprawę, że lista (()) również tworzy listę, więc wypróbowałem pozornie proste:
ale to było wolniejsze niż sygnał gwiezdny.
Wniosek: dla maniaków prędkości: używaj rozumienia listy. Wywołaj funkcje tylko, jeśli musisz. Użyj wbudowanych.
źródło