Co za różnica?
Jakie są zalety / wady krotek / list?
list
. ; D
Co za różnica?
Jakie są zalety / wady krotek / list?
list
. ; D
Odpowiedzi:
Oprócz krotek niezmiennych istnieje również semantyczne rozróżnienie, które powinno kierować ich użyciem. Krotki są heterogenicznymi strukturami danych (tzn. Ich wpisy mają różne znaczenie), podczas gdy listy są jednorodnymi sekwencjami. Krotki mają strukturę, listy mają porządek.
Dzięki temu rozróżnieniu kod jest bardziej wyraźny i zrozumiały.
Jednym z przykładów mogą być pary stron i numerów wierszy do referencyjnych lokalizacji w książce, np .:
my_location = (42, 11) # page number, line number
Następnie możesz użyć tego jako klucza w słowniku do przechowywania notatek na temat lokalizacji. Z drugiej strony listę można wykorzystać do przechowywania wielu lokalizacji. Oczywiście można chcieć dodawać lub usuwać lokalizacje z listy, więc sensowne jest, aby listy można modyfikować. Z drugiej strony dodawanie lub usuwanie elementów z istniejącej lokalizacji nie ma sensu - dlatego krotki są niezmienne.
Mogą wystąpić sytuacje, w których chcesz zmienić elementy w krotce istniejącej lokalizacji, na przykład podczas iteracji po wierszach strony. Ale niezmienność krotki zmusza do utworzenia nowej krotki lokalizacji dla każdej nowej wartości. Na pierwszy rzut oka wydaje się to niewygodne, ale korzystanie z niezmiennych danych takich jak ta jest kamieniem węgielnym typów wartości i technik programowania funkcjonalnego, które mogą mieć znaczące zalety.
Istnieje kilka interesujących artykułów na ten temat, np. „Krotki w Pythonie to nie tylko stałe listy” lub „Zrozumienie krotek vs. list w Pythonie” . Oficjalna dokumentacja Pythona również o tym wspomina
„Krotki są niezmienne i zwykle zawierają heterogeniczną sekwencję ...”.
W języku o typie statycznym, takim jak Haskell, wartości w krotce mają na ogół różne typy i długość krotki musi być stała. Na liście wszystkie wartości mają ten sam typ, a długość nie jest stała. Różnica jest więc bardzo oczywista.
Wreszcie w Pythonie znajduje się nazwa- nazwa , co ma sens, ponieważ krotka ma już strukturę. Podkreśla to ideę, że krotki są lekką alternatywą dla klas i instancji.
collections.namedtuple
że lepiej byłoby zadzwonić collections.record
. Nie ma sensu zamieniać, powiedzmy, nazwy i adresu w rejestrze klienta; w rzeczywistości byłoby to zasadniczo błędem, którego niezmienność krotki uniemożliwia popełnienie.
What would you do with such a list?
, zawsze trzęsę się , gdy ppl używa argumentu braku fantazji. Korzystanie z list typów mieszanych działa świetnie np. W przypadku niektórych hierarchicznych struktur danych, gdzie każda lista składa się z list potomnych i elementów wartości.
Różnica między listą a krotką
Dosłowny
someTuple = (1,2)
someList = [1,2]
Rozmiar
a = tuple(range(1000))
b = list(range(1000))
a.__sizeof__() # 8024
b.__sizeof__() # 9088
Ze względu na mniejszy rozmiar operacji krotki staje się ona nieco szybsza, ale nie wspominając o niej aż do momentu, gdy będziesz mieć ogromną liczbę elementów.
Dozwolone operacje
b = [1,2]
b[0] = 3 # [3, 2]
a = (1,2)
a[0] = 3 # Error
Oznacza to również, że nie można usunąć elementu ani posortować krotki. Możesz jednak dodać nowy element do listy i krotki z tą różnicą, że ponieważ krotka jest niezmienna, tak naprawdę nie dodajesz elementu, ale tworzysz nową krotkę, więc identyfikator zmieni się
a = (1,2)
b = [1,2]
id(a) # 140230916716520
id(b) # 748527696
a += (3,) # (1, 2, 3)
b += [3] # [1, 2, 3]
id(a) # 140230916878160
id(b) # 748527696
Stosowanie
Ponieważ lista jest zmienna, nie można jej używać jako klucza w słowniku, natomiast można użyć krotki.
a = (1,2)
b = [1,2]
c = {a: 1} # OK
c = {b: 1} # Error
3. Permitted operation
pokazuje najpierw krotkę. Wiem, że zwykle udaje się wykazać sukces, a potem błąd, ale to przez chwilę pomieszało mi się z głową.
one_item_list = [a]
, ale one_tuple = (a,)
jest odpowiednią krotką. Zwróć uwagę na przecinek następujący po nazwie zmiennej. Ale uwaga two_tuple = (a, b)
. To mnie odrzuciło więcej niż jeden raz (wciąż tam w Pythonie 3).
tuple(sorted(the_unsorted_tuple))
Jeśli wybrałeś się na spacer, w (x,y)
krotce możesz zanotować swoje współrzędne .
Jeśli chcesz nagrać swoją podróż, możesz co kilka sekund dołączyć swoją lokalizację do listy.
Ale nie można tego zrobić na odwrót.
Kluczową różnicą jest to, że krotki są niezmienne. Oznacza to, że nie można zmienić wartości w krotce po jej utworzeniu.
Więc jeśli będziesz musiał zmienić wartości, użyj listy.
Korzyści z krotek:
frozenset
różne mrożone dict / tree / etc innych firm. typy, ale żaden z nich nie pozwala na dodawanie zmiennych elementów. (I oczywiście krotka jest haszowalna tylko wtedy, gdy wszystkie jej elementy są, co jest obsługiwane w zwykły sposób d[1, [2]]
TypeError: unhashable type: 'list'
Listy są zmienne; krotki nie są.
Od docs.python.org/2/tutorial/datastructures.html
Krotki są niezmienne i zwykle zawierają heterogeniczną sekwencję elementów, do których można uzyskać dostęp poprzez rozpakowanie (patrz dalej w tym rozdziale) lub indeksowanie (lub nawet przez atrybut w przypadku nazwanych). Listy można modyfikować, a ich elementy są zwykle jednorodne i można uzyskać do nich dostęp poprzez iterację po liście.
To zostało wspomniane , że różnica jest w dużej mierze semantyczny: ludzie oczekują krotki i lista reprezentować różne informacje. Ale to wykracza poza wytyczne; niektóre biblioteki faktycznie zachowują się inaczej w zależności od tego, co są przekazywane. Weźmy na przykład NumPy (skopiowane z innego postu, w którym proszę o więcej przykładów):
>>> import numpy as np
>>> a = np.arange(9).reshape(3,3)
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> idx = (1,1)
>>> a[idx]
4
>>> idx = [1,1]
>>> a[idx]
array([[3, 4, 5],
[3, 4, 5]])
Chodzi o to, że chociaż NumPy może nie być częścią standardowej biblioteki, jest to główna biblioteka Pythona, a na listach i krotkach NumPy istnieją zupełnie inne rzeczy.
type(a_list) != type(a_tuple)
, każda gałąź kodu oparta na bibliotece type(x)
zachowuje się inaczej
'%d %d' % [2, 3]
jest TypeError
, ponieważ próbujesz przekazać listę do pierwszego %d
i nie przekazujesz żadnej wartości do drugiego %d
. (Jednak istnieją też kontrprzykłady, takie jak max
...)
Listy są do zapętlania, krotki są do struktur tj "%s %s" %tuple
.
Listy są zwykle jednorodne, krotki są zwykle niejednorodne.
Listy są dla zmiennej długości, krotki dla stałej długości.
Oto przykład list w języku Python:
my_list = [0,1,2,3,4]
top_rock_list = ["Bohemian Rhapsody","Kashmir","Sweet Emotion", "Fortunate Son"]
Oto przykład krotki Python:
my_tuple = (a,b,c,d,e)
celebrity_tuple = ("John", "Wayne", 90210, "Actor", "Male", "Dead")
Listy i krotki w języku Python są podobne, ponieważ oba są uporządkowanymi zbiorami wartości. Oprócz niewielkiej różnicy, że listy są tworzone za pomocą nawiasów „[..., ...]” i krotek za pomocą nawiasów „(..., ...)”, podstawowa techniczna „zakodowana na stałe w składni Python” różnica między nimi jest to, że elementy konkretnej krotki są niezmienne, podczas gdy listy są zmienne (... więc tylko krotki są haszowalne i mogą być używane jako klucze słownikowe / mieszające!). Powoduje to różnice w tym, w jaki sposób można lub nie można ich używać (wymuszone a priori przez składnię) oraz różnice w sposobie, w jaki ludzie decydują się na ich użycie (zachęcane jako „najlepsze praktyki”, a posteriori, to właśnie robią inteligentni programiści ). ludzie podają porządek elementów.
W przypadku krotek „porządek” oznacza jedynie specyficzną „strukturę” do przechowywania informacji. Jakie wartości znajdują się w pierwszym polu, można łatwo zamienić na drugie pole, ponieważ każda z nich podaje wartości w dwóch różnych wymiarach lub skalach. Dostarczają odpowiedzi na różnego rodzaju pytania i mają zazwyczaj formę: jakie są atrybuty danego obiektu / przedmiotu? Obiekt / przedmiot pozostaje stały, atrybuty się różnią.
W przypadku list „kolejność” oznacza sekwencję lub kierunkowość. Drugi element MUSI występować po pierwszym elemencie, ponieważ jest ustawiony na 2. miejscu w oparciu o określoną i wspólną skalę lub wymiar. Elementy są traktowane jako całość i najczęściej dostarczają odpowiedzi na pojedyncze pytanie, typowo, dla danego atrybutu, w jaki sposób te obiekty / przedmioty są porównywane? Atrybut pozostaje stały, obiekt / przedmiot różni się.
Istnieją niezliczone przykłady ludzi w kulturze popularnej i programistów, którzy nie zgadzają się z tymi różnicami, i są niezliczeni ludzie, którzy mogliby użyć widelca do sałatek do dania głównego. Pod koniec dnia wszystko jest w porządku i oboje zazwyczaj mogą wykonać zadanie.
Podsumowując niektóre drobniejsze szczegóły
Podobieństwa:
Indeksowanie, zaznaczanie i krojenie - Zarówno krotki, jak i listy indeksują przy użyciu wartości całkowitych znalezionych w nawiasach. Więc jeśli chcesz pierwsze 3 wartości z danej listy lub krotki, składnia byłaby taka sama:
>>> my_list[0:3]
[0,1,2]
>>> my_tuple[0:3]
[a,b,c]
Porównywanie i sortowanie - Dwie krotki lub dwie listy są porównywane według pierwszego elementu, a jeśli istnieje remis, to według drugiego elementu i tak dalej. Nie zwraca się dalszej uwagi na kolejne elementy, ponieważ wcześniejsze elementy wykazują różnicę.
>>> [0,2,0,0,0,0]>[0,0,0,0,0,500]
True
>>> (0,2,0,0,0,0)>(0,0,0,0,0,500)
True
Różnice: - A priori, z definicji
Składnia - użycie list [], użycie krotek ()
Zmienność - elementy na danej liście są zmienne, elementy w danej krotce NIE są zmienne.
# Lists are mutable:
>>> top_rock_list
['Bohemian Rhapsody', 'Kashmir', 'Sweet Emotion', 'Fortunate Son']
>>> top_rock_list[1]
'Kashmir'
>>> top_rock_list[1] = "Stairway to Heaven"
>>> top_rock_list
['Bohemian Rhapsody', 'Stairway to Heaven', 'Sweet Emotion', 'Fortunate Son']
# Tuples are NOT mutable:
>>> celebrity_tuple
('John', 'Wayne', 90210, 'Actor', 'Male', 'Dead')
>>> celebrity_tuple[5]
'Dead'
>>> celebrity_tuple[5]="Alive"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
Tablice skrótów (słowniki) - Ponieważ tabele skrótów (słowniki) wymagają, aby klucze były haszowalne, a zatem niezmienne, tylko krotki mogą działać jako klucze słownika, a nie listy.
#Lists CAN'T act as keys for hashtables(dictionaries)
>>> my_dict = {[a,b,c]:"some value"}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
#Tuples CAN act as keys for hashtables(dictionaries)
>>> my_dict = {("John","Wayne"): 90210}
>>> my_dict
{('John', 'Wayne'): 90210}
Różnice - a posteriori, w użyciu
Homo vs. heterogeniczność elementów - obiekty listy na ogół są jednorodne, a obiekty krotkowe są heterogeniczne. Oznacza to, że listy są używane dla obiektów / przedmiotów tego samego typu (jak wszyscy kandydaci na prezydenta, wszystkie piosenki lub wszyscy biegacze), podczas gdy chociaż nie jest to wymuszone), podczas gdy krotki są bardziej dla obiektów heterogenicznych.
Pętla a struktury - Mimo że oba pozwalają na zapętlenie (dla x na mojej liście_m_ ...), to naprawdę ma sens, aby to zrobić tylko dla listy. Krotki są bardziej odpowiednie do tworzenia struktury i prezentacji informacji (% s% s przebywający w% s to% si obecnie% s% („John”, „Wayne”, 90210, „Actor”, „Dead”))
Wartości listy można zmienić w dowolnym momencie, ale wartości krotek nie można zmienić.
Te zalety i wady zależy od zastosowania. Jeśli masz takie dane, których nigdy nie chcesz zmieniać, powinieneś użyć krotki, w przeciwnym razie lista jest najlepszą opcją.
Krotki i listy są pozornie podobnymi typami sekwencji w Pythonie.
Dosłowna składnia
Używamy nawiasów ( ) do tworzenia krotek i nawiasów kwadratowych w
[ ]
celu uzyskania nowej listy. Możemy również użyć wywołania odpowiedniego typu, aby uzyskać wymaganą strukturę - krotkę lub listę.
someTuple = (4,6)
someList = [2,6]
Zmienność
Krotki są niezmienne, podczas gdy listy są zmienne. Ten punkt jest podstawą dla następujących.
Zużycie pamięci
Ze względu na zmienność potrzebujesz więcej pamięci na listy i mniej pamięci na krotki.
Rozsuwalny
Możesz dodać nowy element zarówno do krotek, jak i list, z tą różnicą, że identyfikator krotki zostanie zmieniony (tj. Będziemy mieli nowy obiekt).
Hashowanie
Krotki są haszowalne, a listy nie. Oznacza to, że możesz użyć krotki jako klucza w słowniku. Listy nie można użyć jako klucza w słowniku, natomiast można użyć krotki
tup = (1,2)
list_ = [1,2]
c = {tup : 1} # ok
c = {list_ : 1} # error
Semantyka
Ten punkt dotyczy bardziej najlepszych praktyk. Należy używać krotek jako heterogenicznych struktur danych, podczas gdy listy są jednorodnymi sekwencjami.
Listy mają być homogenicznymi sekwencjami, a krotki są heterogenicznymi strukturami danych.
Jak już odpowiedzieli ludzie, którzy tuples
są niezmienni, a jednocześnie lists
zmienni, ale istnieje jeden ważny aspekt korzystania z krotek, o którym musimy pamiętać
Jeśli tuple
zawiera a list
lub dictionary
wewnątrz, można je zmienić, nawet jeśli tuple
sam jest niezmienny.
Załóżmy na przykład, że mamy krotkę zawierającą listę i słownik as
my_tuple = (10,20,30,[40,50],{ 'a' : 10})
możemy zmienić zawartość listy jako
my_tuple[3][0] = 400
my_tuple[3][1] = 500
co sprawia, że wygląda nowa krotka
(10, 20, 30, [400, 500], {'a': 10})
możemy również zmienić słownik wewnątrz krotki jako
my_tuple[4]['a'] = 500
dzięki czemu będzie wyglądać ogólna krotka
(10, 20, 30, [400, 500], {'a': 500})
Dzieje się tak dlatego, list
i dictionary
są obiekty i przedmioty te nie zmieniają, ale zawartość jego skierowana.
tuple
Pozostaje więc niezmienny bez żadnych wyjątków
PEP 484 - Rodzaj wskazówki mówi, że rodzaje elementów tuple
może być indywidualnie wpisane; abyś mógł powiedzieć Tuple[str, int, float]
; ale a list
, z List
klasą typowania, może przyjąć tylko jeden parametr typu: List[str]
co wskazuje, że różnica 2 jest taka, że pierwszy jest heterogeniczny, podczas gdy drugi jest z natury jednorodny.
Również biblioteka standardowa używa krotki jako wartości zwracanej od takich standardowych funkcji, w których C zwróciłoby a struct
.
Jak ludzie wspominali już o różnicach, napiszę o tym, dlaczego krotki.
Dlaczego krotki są preferowane?
Optymalizacja alokacji dla małych krotek
Aby zmniejszyć fragmentację pamięci i przyspieszyć przydziały, Python używa starych krotek. Jeśli krotka nie jest już potrzebna i ma mniej niż 20 elementów zamiast trwale ją usunąć, Python przenosi ją na darmową listę.
Darmowa lista jest podzielona na 20 grup, przy czym każda grupa reprezentuje listę krotek o długości n od 0 do 20. Każda grupa może przechowywać do 2 000 krotek. Pierwsza (zero) grupa zawiera tylko 1 element i reprezentuje pustą krotkę.
>>> a = (1,2,3)
>>> id(a)
4427578104
>>> del a
>>> b = (1,2,4)
>>> id(b)
4427578104
W powyższym przykładzie widzimy, że aib mają ten sam identyfikator. To dlatego, że natychmiast zajęliśmy zniszczoną krotkę, która była na liście darmowej.
Optymalizacja alokacji dla list
Ponieważ listy można modyfikować, Python nie stosuje takiej samej optymalizacji jak w krotkach. Jednak listy w języku Python mają również listę bezpłatną, ale jest używana tylko do pustych obiektów. Jeśli pusta lista zostanie usunięta lub zebrana przez GC, można ją ponownie wykorzystać później.
>>> a = []
>>> id(a)
4465566792
>>> del a
>>> b = []
>>> id(b)
4465566792
Źródło: https://rushter.com/blog/python-lists-and-tuples/
Dlaczego krotki są wydajniejsze niż listy? -> https://stackoverflow.com/a/22140115
Cytat kierunkowy z dokumentacji na 5.3. Krotki i sekwencje :
Chociaż krotki mogą wydawać się podobne do list, często są używane w różnych sytuacjach i do różnych celów. Krotki są niezmienne i zwykle zawierają heterogeniczną sekwencję elementów, do których dostęp uzyskuje się poprzez rozpakowanie (patrz dalej w tym rozdziale) lub indeksowanie (lub nawet przez atrybut w przypadku nazwanych). Listy można modyfikować , a ich elementy są zwykle jednorodne i można uzyskać do nich dostęp poprzez iterację po liście.
Po pierwsze, oba są obiektami nieskalarnymi (znanymi również jako obiekty złożone) w Pythonie.
+
(oczywiście zostanie utworzona nowa krotka)(3,) # -> (3)
zamiast(3) # -> 3
[3]
new_array = origin_array[:]
[x**2 for x in range(1,7)]
daje
[1,4,9,16,25,36]
(nieczytelne)Korzystanie z listy może również powodować błąd aliasingu (dwie różne ścieżki wskazujące na ten sam obiekt).
Listy są zmienne, a krotki są niezmienne. Rozważ ten przykład.
a = ["1", "2", "ra", "sa"] #list
b = ("1", "2", "ra", "sa") #tuple
Teraz zmień wartości indeksu listy i krotki.
a[2] = 1000
print a #output : ['1', '2', 1000, 'sa']
b[2] = 1000
print b #output : TypeError: 'tuple' object does not support item assignment.
W związku z tym udowodniono, że poniższy kod jest nieprawidłowy w przypadku krotki, ponieważ próbowaliśmy zaktualizować krotkę, co jest niedozwolone.
Lista jest zmienna, a krotki są niezmienne. Główną różnicą między zmienną i niezmienną jest użycie pamięci podczas próby dołączenia elementu.
Podczas tworzenia zmiennej część stałej pamięci jest przypisywana do zmiennej. Jeśli jest to lista, przydzielana jest więcej pamięci niż faktycznie używana. Np. Jeśli bieżące przypisanie pamięci wynosi 100 bajtów, gdy chcesz dodać 101. bajt, być może zostanie przypisanych kolejnych 100 bajtów (w tym przypadku ogółem 200 bajtów).
Jeśli jednak wiesz, że często nie dodajesz nowych elementów, powinieneś użyć krotek. Krotki przypisują dokładnie potrzebny rozmiar pamięci, a tym samym oszczędzają pamięć, zwłaszcza gdy używasz dużych bloków pamięci.