Python List vs. Array - kiedy używać?


374

Jeśli tworzysz tablicę 1d, możesz zaimplementować ją jako Listę lub użyć modułu „tablica” w standardowej bibliotece. Zawsze używałem list do tablic 1d.

Jaki jest powód lub okoliczność, w której chciałbym zamiast tego użyć modułu macierzy?

Czy chodzi o optymalizację wydajności i pamięci, czy brakuje mi czegoś oczywistego?

Odpowiedzi:


438

Zasadniczo listy w języku Python są bardzo elastyczne i mogą przechowywać całkowicie heterogeniczne, dowolne dane, i można je bardzo skutecznie dołączać w zamortyzowanym stałym czasie . Jeśli chcesz zmniejszyć i rozbudować listę w sposób wydajny i bezproblemowy, są na to. Ale oni wykorzystywać przestrzeń dużo więcej niż macierze C .

Z array.arraydrugiej strony ten typ jest po prostu cienkim opakowaniem na tablicach C. Może przechowywać tylko jednorodne dane, wszystkie tego samego typu, a więc wykorzystuje tylko sizeof(one object) * lengthbajty pamięci. Przeważnie powinieneś go używać, gdy chcesz wystawić tablicę C na rozszerzenie lub wywołanie systemowe (na przykład ioctllub fctnl).

array.arrayjest również rozsądnym sposobem reprezentowania łańcucha zmiennego w Pythonie 2.x ( array('B', bytes)). Jednak Python 2.6+ i 3.x oferują zmienny ciąg bajtów jako bytearray.

Jeśli jednak chcesz wykonywać matematykę na jednorodnej tablicy danych liczbowych, znacznie lepiej jest użyć NumPy, który może automatycznie wektoryzować operacje na złożonych tablicach wielowymiarowych.

Krótko mówiąc : array.arrayjest przydatny, gdy potrzebujesz jednorodnej tablicy danych C z powodów innych niż matematyka .


9
Czy numpy.ndarray ma taki sam ślad pamięciowy jak array.array?
Gordon Bean

6
@ Gordon, powinno być bardzo podobne w przypadku dużej, ciągłej tablicy: oba będą wymagały sizeof(element)× (liczba elementów) bajtów plus mały stały nagłówek narzutu. Jednak ndarray ma kilka zaawansowanych opcji radzenia sobie z nieciągłymi i rzadkimi tablicami i myślę, że niektóre wtykowe strategie alokacji pamięci dla dużych tablic ... niektóre z tych zaawansowanych funkcji sprawią, że będzie mniej pamięci użytkownika , podczas gdy inne poprawią wydajność poprzez użycie więcej pamięć.
Dan Lenski

Przydatne również, gdy pamięć stanowi problem, np. Podczas programowania mikrokontrolerów za pomocą mikrofonu
janscas

Można wyszukać i-ty element tablicy w stałym czasie, podczas gdy na połączonej liście w najgorszym przypadku przyjmuje on porządek „n”. Jaki jest czas wyszukiwania i-tego elementu na liście python?
Nithish Inpursuit Ofhappiness

7
@NithishInpursuitOfhappiness, lista Python nie jest listą połączoną. Jest on reprezentowany wewnętrznie jako tablica i ma te same cechy złożoności czasowej co ArrayList Javy. Zatem uzyskanie i ustawienie i-tego elementu listy Pythona zajmuje stały czas . Dołączenie elementu do listy w języku Python wymaga zamortyzowanego stałego czasu, ponieważ rozmiar tablicy jest podwojony, gdy zabraknie miejsca. Wstawianie elementu do lub usuwanie ze środka listy Pythona zajmuje O (n) czasu, ponieważ elementy muszą zostać przesunięte. W celach
geofflee,

66

W prawie wszystkich przypadkach normalna lista jest właściwym wyborem. Moduł tablic przypomina bardziej cienkie opakowanie nad tablicami C, które dają rodzaj silnie typowanych kontenerów (patrz dokumenty ), z dostępem do bardziej podobnych do C typów, takich jak podpisane / niepodpisane krótkie lub podwójne, które nie są częścią wbudowanego -w typach. Powiedziałbym, że używaj modułu tablic tylko wtedy, gdy naprawdę go potrzebujesz, we wszystkich innych przypadkach trzymaj się list.


3
Możliwe, ale tak naprawdę nigdy go nie użyłem, ale byłoby interesujące uruchomić kilka mikroprocesorów.
André

13
Właściwie zrobiłem szybki test - zsynchronizowałem sumowanie listy ze 100 milionami wpisów i ten sam test z odpowiednią tablicą, a lista była w rzeczywistości o około 10% szybsza.
Moe

38
Listy są szybsze, ponieważ operacje na „surowych” danych z tablicy muszą stale tworzyć i niszczyć obiekty Pythona podczas odczytu lub zapisu w tablicy.
tzot

7
@Moe, jak wskazałem w mojej odpowiedzi powyżej, wbudowany Python niearray jest przeznaczony do robienia matematyki . Jeśli spróbujesz NumPy ndarraydo zsumowania tablicy 10 ^ 8 liczb, to całkowicie rozwali list. @tzot ma słuszne wyobrażenie o tym, dlaczego wbudowane funkcje arraymatematyczne są wolne.
Dan Lenski

2
Właśnie go przetestowałem, numpy jest 86,6 razy szybszy na moim komputerze.
Mark

53

Moduł macierzowy jest jedną z tych rzeczy, których prawdopodobnie nie potrzebujesz, jeśli nie wiesz, dlaczego go użyjesz (i zauważ, że nie próbuję tego powiedzieć protekcjonalnie!) . Przez większość czasu moduł tablicowy służy do interfejsu z kodem C. Aby udzielić bardziej bezpośredniej odpowiedzi na pytanie dotyczące wydajności:

W niektórych zastosowaniach tablice są bardziej wydajne niż listy. Jeśli musisz przydzielić tablicę, której WIEDZIE nie zmieni, tablice mogą być szybsze i zużywać mniej pamięci. GvR ma anegdotę dotyczącą optymalizacji, w której moduł macierzy okazuje się zwycięzcą (długi odczyt, ale warto).

Z drugiej strony, jednym z powodów, dla których listy pochłaniają więcej pamięci niż tablice, jest to, że Python przydzieli kilka dodatkowych elementów, gdy wszystkie przydzielone elementy zostaną wykorzystane. Oznacza to, że dodawanie elementów do list jest szybsze. Więc jeśli planujesz dodać elementy, lista jest właściwą drogą.

TL; DR Użyłbym tablicy tylko wtedy, gdy potrzebujesz wyjątkowej optymalizacji lub potrzebujesz interfejsu z kodem C (i nie możesz używać pyrex ).


1
+1 za konkretny przykład i wzmiankę o korzyściach z prędkości. Najlepsza odpowiedź sprawiła, że ​​zastanawiałem się: „Czy istnieje kompromis w zakresie pamięci czasu?” i „Czy ma to jakikolwiek użytek, który nie jest zbyt ezoterycznym przypadkiem małej pamięci?”
leewz

@leewz dokładnie, należy to uznać za odpowiedź.
Gauri Shankar Badola

21

To jest kompromis!

zalety każdego z nich:

lista

  • elastyczne
  • może być heterogeniczny

tablica (np. tablica numpy)

  • tablica jednolitych wartości
  • jednorodny
  • kompaktowy (w rozmiarze)
  • wydajny (funkcjonalność i szybkość)
  • wygodna

2
pytanie dotyczy modułu tablicy w pythonie; nie tablice numpy. Nie mają wielu zalet oprócz wydajności rozmiaru. Nie są szybsi.
NONONONONO

14

Rozumiem, że tablice są przechowywane bardziej wydajnie (tj. Jako ciągłe bloki pamięci vs. wskaźniki do obiektów Pythona), ale nie jestem świadomy żadnych korzyści w zakresie wydajności. Dodatkowo w przypadku tablic musisz przechowywać prymitywy tego samego typu, podczas gdy listy mogą przechowywać wszystko.


8

Standardowe tablice biblioteczne są przydatne do binarnych operacji we / wy, takich jak tłumaczenie listy liczb całkowitych na ciąg znaków do zapisu, powiedzmy, do pliku wave. To powiedziawszy, jak już wielu zauważyło, jeśli zamierzasz wykonać jakąkolwiek prawdziwą pracę, powinieneś rozważyć użycie NumPy.


6

Jeśli zamierzasz używać tablic, rozważ pakiety numpy lub scipy, które dają tablice o wiele większej elastyczności.


5

Tablicy można używać tylko do określonych typów, natomiast list można używać do dowolnego obiektu.

Tablice mogą również zawierać dane tylko jednego typu, podczas gdy lista może zawierać wpisy różnych typów obiektów.

Tablice są również bardziej wydajne w przypadku niektórych obliczeń numerycznych.


4
Wbudowane tablice python nie są wydajne pod względem wydajności, tylko pod względem pamięci.
tzot

Istnieją przypadki, w których tablice są bardziej wydajne pod względem przetwarzania. Zobacz mój post poniżej: stackoverflow.com/questions/176011/…
Jason Baker

0

Ważną różnicą między tablicą numpy a listą jest to, że wycinki tablic są widokami oryginalnej tablicy. Oznacza to, że dane nie są kopiowane, a wszelkie modyfikacje widoku zostaną odzwierciedlone w tablicy źródłowej.


0

Ta odpowiedź podsumuje prawie wszystkie zapytania dotyczące tego, kiedy użyć List i Array:

  1. Główną różnicą między tymi dwoma typami danych są operacje, które można na nich wykonać. Na przykład możesz podzielić tablicę przez 3, a ona podzieli każdy element tablicy przez 3. Tego samego nie można zrobić z listą.

  2. Lista jest częścią składni Pythona, więc nie trzeba jej deklarować, a przed użyciem należy zadeklarować tablicę.

  3. Możesz przechowywać wartości różnych typów danych na liście (heterogeniczne), podczas gdy w tablicy możesz przechowywać tylko wartości tylko tego samego typu danych (jednorodne).

  4. Tablice są bogate w funkcje i szybkie, jest szeroko stosowane do operacji arytmetycznych i do przechowywania dużej ilości danych - w porównaniu do listy.

  5. Tablice zajmują mniej pamięci w porównaniu do list.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.