Python Tuple vs List: Podobnosti a rozdíly, vysvětleno

V této příručce se dozvíte podobnosti a rozdíly mezi pythonskými n-ticemi a seznamy. Také pochopíte, kdy byste měli použít n-tici.

Seznam a n-tice jsou vestavěné datové struktury v Pythonu. Lze je použít k uložení kolekce prvků.

Od podpory indexování a dělení až po heterogenní datové typy se může zdát, že n-tice a seznamy mají podobné funkce. Pochopení podobností a rozdílů mezi těmito dvěma vám proto může pomoci při rozhodování, kterou datovou strukturu použít.

Pojďme začít.

👩🏽‍💻 Můžete spustit Python REPL a postupovat podle tohoto návodu. Pro kódování můžete také použít etechblog.cz online editor Pythonu.

Python Tuple vs List: Jaké jsou podobnosti?

Začněme tím, že se naučíme podobnosti mezi seznamy a n-ticemi. Pro usnadnění lepšího učení uvádíme příklady seznamů i n-tic.

#1. Python Iterables

V Pythonu jsou seznamy uzavřeny do dvojice hranatých závorek, zatímco n-tice jsou uzavřeny v závorkách. N-tici můžete také vytvořit jako sadu hodnot oddělených čárkami – bez závorek.

Oba jsou iterovatelné; takže je můžete procházet pomocí smyčky for.

Buňka kódu níže ukazuje, jak iterovat seznamem.

nums = [2,6,7,10]
print(f"Type of nums is {type(nums)}")
for num in nums:
  print(num)

# Output
Type of nums is <class 'list'>
2
6
7
10

Jak je vysvětleno níže, můžete také iterovat n-ticí pomocí smyčky

nums = (2,6,7,10)

# Note: nums = 2,6,7,10 is a valid tuple as well. If needed, run a quick check!

print(f"Type of nums is {type(nums)}")
for num in nums:
  print(num)

# Output
Type of nums is <class 'tuple'>
2
6
7
10

#2. Podpora pro tvorbu z jiných sekvencí

Další podobnost mezi seznamy a n-ticemi spočívá v tom, že je lze vytvořit z existujících sekvencí, jako jsou řetězce.

sample_str = "Coding!"

Následující buňka kódu ukazuje, jak list(string) vrací seznam, jehož položky seznamu jsou znaky v řetězci.

list_from_str = list(sample_str)
print(list_from_str)

# Output
['C', 'o', 'd', 'i', 'n', 'g', '!']

Podobně lze n-tice vytvořit z řetězce nebo jiné sekvence pomocí n-tice (sekvence). Níže uvedená buňka kódu ukazuje, jak to můžete udělat.

tuple_from_str = tuple(sample_str)
print(tuple_from_str)

# Output
('C', 'o', 'd', 'i', 'n', 'g', '!')

#3. Podpora pro indexování a krájení

Python podporuje nulové indexování, ve kterém je první prvek na indexu nula, druhý na indexu jedna atd. Python také podporuje záporné indexování, kde je poslední prvek na indexu -1, předposlední prvek je na indexu -2 a tak dále.

list_from_str = ['C', 'o', 'd', 'i', 'n', 'g', '!']
print(list_from_str[1])
# o

Položka na indexu -2 je předposlední položka, ‚g‘.

tuple_from_str = ('C', 'o', 'd', 'i', 'n', 'g', '!')
print(tuple_from_str[-2])
# g

Dělení můžete použít, když chcete pracovat s malou částí seznamu nebo n-tice. seznam[start:end] vrací část seznamu začínající na začátku indexu a rozšiřující se až do konce – 1. Výchozí hodnota pro začátek je 0 a konec je poslední prvek v iteraci.

Pomocí stejné syntaxe můžete dělit n-tice. Vytvořme řezy seznamu a n-tice, které jsme vytvořili dříve.

list_from_str = ['C', 'o', 'd', 'i', 'n', 'g', '!']
print(list_from_str[0:5])

['C', 'o', 'd', 'i', 'n']

Kromě počáteční a koncové hodnoty můžete zadat také hodnotu kroku. tuple(start:end:step) vrací část n-tice od začátku do konce – 1, v krocích po kroku.

tuple_from_str = ('C', 'o', 'd', 'i', 'n', 'g', '!')
print(tuple_from_str[::2])

('C', 'd', 'n', '!')

Zde nastavíme hodnotu kroku na 2. Řez tedy obsahuje každý druhý prvek.

#4. Kolekce více datových typů

V příkladech, které jsme zvažovali, byly všechny položky v seznamu a n-tice stejného datového typu.

V rámci jednoho seznamu nebo n-tice však můžete uložit hodnoty různých datových typů.

Fragment kódu pod student_list obsahuje jméno studenta jako řetězec, věk jako celé číslo a značky zabezpečené jako float.

student_list = ["John",22,96.5]
for item in student_list:
  print(f"{item} is of type {type(item)}")

# Output
John is of type <class 'str'>
22 is of type <class 'int'>
96.5 is of type <class 'float'>

Můžeme přijít s podobným příkladem pro n-tici.

student_tuple = ("Jane",23,99.5)
for item in student_tuple:
  print(f"{item} is of type {type(item)}")

# Output
Jane is of type <class 'str'>
23 is of type <class 'int'>
99.5 is of type <class 'float'>

#5. Podpora pro testování členství

Seznamy i n-tice umožňují provádět testování členství na přítomnost určitých položek. Pokud chcete zkontrolovat, zda je konkrétní položka přítomna v seznamu nebo n-tici, můžete použít operátor in.

Položka výrazu v iterable se vyhodnotí jako True, pokud iterable položku obsahuje; jinak False.

"Alex" in student_list
# False

"Jane" in student_tuple
# True

Zatím jste se naučili podobnosti mezi seznamy a n-ticemi v Pythonu. Dále se naučíme klíčové rozdíly mezi těmito dvěma datovými strukturami.

Python Tuple vs List: Jaké jsou rozdíly?

#1. Proměnlivost seznamů a neměnnost n-tic v Pythonu

Nejzásadnější rozdíl mezi seznamem a n-ticí v Pythonu je ten, že n-tice je neměnná. To znamená, že nemůžete upravit n-tici na místě.

▶️ Zde je příklad.

tuple1 = ("Java","Python","C++")
tuple1[0] = "Rust"

# Output
----> 2 tuple1[0] = "Rust"

TypeError: 'tuple' object does not support item assignment

Seznam je proměnná datová struktura, takže seznam můžeme upravit změnou položky v určitém indexu, jako v následující buňce kódu.

list1 = ["Java","Python","C++"]
list1[0] = "Rust"
print(list1)

# Output
['Rust', 'Python', 'C++']

#2. Seznamy s proměnnou délkou vs. n-tice s pevnou délkou

Python list je datová struktura s proměnnou délkou.

Můžete provést následující:

  • Přidejte položku na konec seznamu
  • Přidejte položky z jiného seznamu na konec aktuálního seznamu
  • Odstraňte položky v konkrétním indexu ze seznamu
list1 = [2,3,4,5]

# add an item to the end
list1.append(9)
print(list1)

# add items from list2 to the end of list1
list2 = [0,7]
list1.extend(list2)
print(list1)

# remove an item from list1
list1.pop(0)
print(list1)

▶️ Výstup výše uvedeného fragmentu kódu.

# Output
[2, 3, 4, 5, 9]
[2, 3, 4, 5, 9, 0, 7]
[3, 4, 5, 9, 0, 7]

N-tice jsou datové struktury s pevnou délkou. Nemůžete tedy přidávat nebo odebírat prvky z existující n-tice. Ale můžete předefinovat n-tici tak, aby obsahovala různé prvky.

tuple1 = (2,4,6,8)
tuple1 = (1,8,9)
print(tuple1)

# Output
(1, 8, 9)

#3. Velikost v paměti

Nyní navážeme na to, co jsme se naučili v předchozí části: seznam je datová struktura s proměnnou délkou.

Když na začátku definujete seznam, je mu v paměti přidělena určitá velikost. Nyní, když upravíte seznam pomocí metod append() nebo extend(), by měla být přidělena další paměť pro uložení přidaných prvků. Tato alokace se téměř vždy provádí více než počet položek, které přidáte.

Je tedy potřeba sledovat počet položek na seznamu a přidělené místo. Kromě toho, protože seznamy mají proměnnou délku, je zde ukazatel, který ukazuje na adresu položek seznamu. Výsledkem je, že seznamy délky k zabírají více paměti než n-tice se stejnými k prvky.

Zde je jednoduchá ilustrace.

K získání velikosti objektu v paměti můžete použít metodu getizeof() vestavěného modulu sys na objektu Pythonu.

import sys

list1 = [4,5,9,14]
list_size = sys.getsizeof(list1)
print(f"Size of list:{list_size}")

tuple1 = (4,5,9,14)
tuple_size = sys.getsizeof(tuple1)
print(f"Size of tuple:{tuple_size}")

Seznam zabírá více paměti než n-tice pro stejný počet a hodnotu prvků, jak je ověřeno ve výstupu níže.

# Output
Size of list:104
Size of tuple:88

Kdy byste měli použít Python Tuple?

Z rozdílů a podobností mezi Pythonovými seznamy a n-ticemi víte, že pokud potřebujete měnitelnou kolekci, měli byste použít seznam.

Ale kdy byste měli místo toho použít n-tici?

To si probereme v této části.

#1. Kolekce pouze pro čtení

Kdykoli chcete, aby byla kolekce neměnná, měli byste ji definovat jako n-tici. Předpokládejme, že barva = (243,55,103) n-tice obsahující hodnoty RGB odpovídající barevnému odstínu. Definování barvy jako n-tice zajišťuje, že ji nelze upravit.

V podstatě, když potřebujete, aby kolekce byla jen pro čtení: hodnoty by se během programu neměly měnit, měli byste zvážit použití n-tice. Tím se zabrání nechtěné změně hodnot.

#2. Klíče slovníku

Například vytvoříte slovník pomocí položek seznamu key_list jako klíčů. K vytvoření slovníku ze seznamu můžete použít metodu dict.fromkeys().

key_list = list("ABCD")
dict.fromkeys(key_list)

{'A': None, 'B': None, 'C': None, 'D': None}

Předpokládejme, že upravíte seznam tak, aby obsahoval ‚D‘ jako první prvek (index 0) – před vytvořením slovníku.

Nyní, co se stane s klíčem slovníku ‚A‘?

Pokud se pokusíte vytvořit slovník ze seznamu klíčů a získat přístup k hodnotě odpovídající klíči ‚A‘, narazíte na chybu KeyError.

key_list[0] = 'D'

dict.fromkeys(key_list)['A']

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-31-c90392acc2cf> in <module>()
----> 1 dict.fromkeys(key_list)['A']

KeyError: 'A'

Klíče slovníku by měly být jedinečné. Nemůžete tedy mít jako klíč druhé „D“.

dict.fromkeys(key_list)
{'B': None, 'C': None, 'D': None} # A is no longer a key.

Pokud místo toho použijete n-tici, taková úprava není možná a je méně pravděpodobné, že narazíte na chyby. Proto byste měli preferovat vytváření slovníku pomocí položek n-tice jako klíčů.

key_tuple = tuple("ABCD")
dict.fromkeys(key_tuple)
{'A': None, 'B': None, 'C': None, 'D': None}

key_tuple[0] = 'D'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-2cecbefa7db2> in <module>()
----> 1 key_tuple[0] = 'D'

TypeError: 'tuple' object does not support item assignment

#3. Funkční argumenty

Neměnnost n-tic je také činí vhodnými pro předávání jako argumenty funkcí.

Zvažte následující funkci find_volume(), která vrací objem kvádru daný rozměry: délka, šířka a výška.

def find_volume(dimensions):
  l,b,h = dimensions
  return l*b*h

Předpokládejme, že tyto dimenze jsou dostupné v seznamu nazvaném dimenze. Volání find_volume() s rozměry jako argument vrátí objem.

dimensions = [2,8,5]
find_volume(dimensions)
80

Rozměry uložené v seznamu můžete kdykoli změnit.

dimensions = [20,8,5]
find_volume(dimensions)
800

Někdy však budete potřebovat, aby hodnoty zůstaly konstantní a odolávaly změnám. Tehdy byste měli zvážit uložení argumentů jako n-tice a jejich použití ve volání funkce.

#4. Návratové hodnoty z funkcí

V Pythonu narazíte na n-tice v návratových hodnotách z funkcí. Když z funkce vrátíte více hodnot, Python je implicitně vrátí jako n-tici.

Zvažte následující funkci return_even():

def return_even(num):
  even = [i for i in range(num) if (i%2==0)]
  return even,len(even)
  • Jako argument bere číslo num
  • Vrátí seznam sudých čísel v intervalu [0,num) and the length of that list.

Let’s set the value of num 20 and call the function.

num = 20

Calling return_even() returns the two values in a tuple. You can call the type() function with the function call as the verification argument.

type(return_even(num)) # <class 'tuple'>

You can print out the return value to verify that it’s a tuple containing the list of even numbers as the first item and the length of the list as the second item.

print(return_even(num))
([0, 2, 4, 6, 8, 10, 12, 14, 16, 18]10)

Protože jsou v n-tice dvě položky, můžete je rozbalit do dvou proměnných, jak je znázorněno níže.

even_nums, count = return_even(num)

print(even_nums)
print(count)

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
10

Závěr

Doufám, že tento tutoriál poskytl komplexní srovnání seznamu Python n-tice vs.

Zakončeme tutoriál rychlým shrnutím:

  • Seznam a n-tice jsou vestavěné datové struktury v Pythonu.
  • Podobnosti: iterovatelné, podpora indexování, dělení, různé datové typy a operátor pro testování členství.
  • Klíčový rozdíl: Seznamy jsou proměnlivé a n-tice jsou neměnné.
  • Další rozdíly: Pevná délka n-tic a proměnná délka seznamů, menší velikost v paměti n-tic.
  • Kdy byste měli použít n-tici? Pro neměnné kolekce, klíče slovníku a argumenty funkcí.

Dále se podívejte na projekty Pythonu, abyste si je mohli procvičit a naučit se. Nebo se naučte metody k odstranění duplicitních položek ze seznamů Pythonu. Šťastné učení! tak šťastné kódování!👩🏽‍💻