Werken met tuples

Inleiding

In voorgaande hoofdstuk leerde je over de list. In dit hoofdstuk leer je over een vergelijkbare collectie: de tuple. Een tuple is zeer vergelijkbaar met een list, behalve dat een tuple niet aanpasbaar (mutable) is. Dit zorgt ervoor dat er bijvoorbeeld geen methodes zijn om elementen toe te voegen of te verwijderen.

Om herhaling te voorkomen, leer je in dit hoofdstuk met name hoe de tuple afwijkt van de list. Overeenkomstige handelingen (zoals for-loops) kun je eventueel teruglezen in eerdere hoofdstukken.

Leerdoelen

Aan het einde van dit hoofdstuk:

  • Begrijp je wat een tuple is

  • Begrijp je in welke situatie je tuples

  • Begrijp je hoe je met elementen in een tuple kunt werken

Tuples: een inleiding

Een tuple is een onveranderlijke collectie, in veel opzichten vergelijkbaar met een list. In deze paragraaf leer je wat de kenmerken van een tuple zijn en wanneer je het in kunt zetten.

Kenmerken van tuples

Een tuple maak je op verschillende manieren:

lege_tuple_1 = ()
lege_tuple_2 = tuple()
tuple_met_items = ("a", "b", 1, 2, )
list_to_tuple = tuple([1, 2, 3, 4, ])

Een tuple bestaat altijd uit één of meerdere elementen geplaatst tussen haakjes (()), gescheiden door een komma. De elementen kunnen verschillende typen gegevens zijn, inclusief andere tuples, lijsten en woordenboeken.

Let op dat als je een tuple wilt maken met maar één element, je niet simpelweg het element tussen haakjes kunt plaatsen. Python zal die haakjes dan namelijk negeren. Om dit te omzeilen plaats je een komma achter het element:

enkel_item = ("a")
print(enkel_item)  # a

enkel_item = ("a", )
print(enkel_item)  # ("a", )

# Je kunt ook de haakjes weglaten
enkel_item = "a",  # Let op de komma
print(enkel_item)

De belangrijkste kenmerken van een tuple zijn:

  • Een tuple is een type collectie en specifieker een reeks.

  • Je haalt waarden op basis van de index op.

  • Een tuple is niet muteerbaar.

  • De elementen hoeven niet van hetzelfde type te zijn.

Omdat een tuple net als een list een reeks is, zijn alle acties die bij een list mogelijk zijn, ook mogelijk bij een tuple:

  • Controleren of het element i in de reeks aanwezig is met i in x

  • Ze samenvoegen met x + y

  • Ze herhalen met x * 3

  • Het aantal elementen ophalen met len(x)

  • Het kleinste en grootste element ophalen met min(x) en max(x)

  • Het aantal elementen tellen met x.count()

  • De index van element i verkrijgen met x.index(i)

Wanneer gebruik je tuples

Een tuple is erg vergelijkbaar met een list, behalve dat een tuple niet aanpasbaar is. Hierdoor is het minder geschikt om te gebruiken om een lijst met elementen op te bouwen, gebruik daarvoor een list.

Een tuple is vooral geschikt voor gegevens die tijdens het verloop van het programma éénmaal worden aangemaakt en vervolgens vaker worden gebruikt. Als je weet dat de reeks niet wijzigt tijdens het programma, is de tuple namelijk efficiënter in gebruik dan een list. Een voorbeeld is het definiëren van een reeks toegestane keuzes in een bepaald formulier:

OPTIONS = (
    (1, "Altijd"),
    (2, "Regelmatig"),
    (3, "Soms"),
    (4, "Zelden"),
    (5, "Nooit"),
)

Zoals je verderop zult zien, is de tuple ook erg handig om een beperkte reeks gegevens in het programma door te geven.

Werken met elementen in een tuple

Omdat werken met elementen in een tuple vrijwel hetzelfde is als werken met elementen in een list, lees je hier alleen de zaken die anders werken. Voor de rest lees je het best nogmaals het hoofdstuk over lijsten.

Sorteren en omkeren

Omdat een tuple niet aanpasbaar is, heeft het geen eigen methodes om te sorteren en om te keren (.sort() en .reverse()). Wel is het mogelijk de ingebouwde functies sorted en reversed te gebruiken. Beiden leveren echter een nieuwe list op, en geen tuple. Uiteraard kun je met tuple() wel weer een tuple van de list maken.

mijn_tuple = ("b", "c", "a", )
gesorteerd = tuple(sorted(mijn_tuple))

print(gesorteerd)
# ('a', 'b', 'c')

Elementen toevoegen en verwijderen

Omdat een tuple niet aanpasbaar is, kun je geen elementen toevoegen of verwijderen.Wil je dit wel doen, dan dien je een nieuw object aan te maken.Bijvoorbeeld:

mijn_tuple = (1, 2, 3, )
print(id(mijn_tuple))  # Een bepaald ID

mijn_tuple = (1, 2, 3, 4)
print(id(mijn_tuple))  # Een ander ID

# Of:
mijn_tuple = (1, 2, 3, )
nieuw_element = 4

mijn_tuple = mijn_tuple + (nieuw_element, )
print(mijn_tuple)
# (1, 2, 3, 4)

Let er in het laatste geval op dat de +-operator alleen gebruikt kan worden tussen twee tuples, daarom is van de variabele nieuw_element eerst een tuple gemaakt (op regel 11).

Uitpakken

Een nog niet genoemd kenmerk van een tuple is dat de haakjes optioneel zijn:

tuple_1 = (1, 2, 3, 4, 5, )
tuple_2 = 1, 2, 3, 4, 5,

print(tuple_1)
# (1, 2, 3, 4, 5)

print(tuple_2)
# (1, 2, 3, 4, 5)

Dat de haakjes worden weggelaten zul je vaak zien bij een manier van werken die specifiek is voor tuples: uitpakken (unpacking).

Uitpakken is het toewijzen van de elementen uit een tuple aan variabelen, in één regel:

a, b = (1, 2)
print(a)  # 1
print(b)  # 2

Op regel één zie je dat een tuple met twee elementen wordt toegewezen aan twee variabelen (gescheiden door een komma). Het eerste element zal worden toegewezen aan de eerste variabele (a) en het tweede element aan de tweede variabele (b). Dit is niet beperkt tot twee elementen/variabelen.

Omdat je de haakjes bij een tupel mag weglaten, levert onderstaande hetzelfde resultaat op:

a, b = 1, 2
print(a)  # 1
print(b)  # 2

Dit uitpakken is met name interessant bij het gebruik van functies, waarover je meer leert in het hoofdstuk Werken met functies. Voor nu is het belangrijk om te begrijpen dat een functie een waarde retourneert (teruggeeft) met return. Datgene wat wordt geretourneerd door een functie, kun je toewijzen aan een variabele.

def mijn_functie():
    # Deze functie geeft altijd "a" terug
    return "a"

# Wijs de uitkomst van de functie toe aan een variabele
a = mijn_functie()
print(a)  # a

Een functie kan echter ook meerdere waarden teruggeven, feitelijk een tuple zonder haakjes. En deze tuple kun je weer uitpakken:

def mijn_functie():
    # Deze functie geeft altijd "a", "b" terug
    return "a", "b"

# Wijs de uitkomst van de functie met uitpakken toe aan twee variabelen
a, b = mijn_functie()
print(a)  # "a"
print(b)  # "b"
Uitpakken

Je kunt een langere tuple ook uitpakken en (bijvoorbeeld) alleen de eerste twee waarden gebruiken:

mijn_tuple = (1, 2, 3, 4, 5)

a, b, *rest = mijn_tuple  # Let op de *

print(a)  # 1
print(b)  # 2
print(rest)  # [3, 4, 5]

In Python is het de gewoonte om een variabele die je verder niet meer gebruikt de naam _ te geven (een _underscore_):

a, b, *_ = mijn_tuple
Opdracht 1: coördinaten

Neem onderstaande tuple met lengte- en breedtegraden:

coordinaten = (
    (52.3702, 4.8952),
    (51.9225, 4.47917),
    (52.0907, 5.12142),
    (50.8503, 4.3517),
    (51.2093, 3.2247)
)

Van elk paar is het eerste getal de breedtegraad en het tweede getal de lengtegraad. Schrijf code dat voor elk paar de volgende zin print:

"Breedtegraad: <getal>, Lengtegraad: <getal>"

Klik om het antwoord te tonen
# Uitwerking zonder uitpakken
for coord in coordinaten:
    print(f"Breedtegraad: {coord[0]}, Lengtegraad: {coord[1]}")

# Uitwerking met uitpakken
for breedte, lengte in coordinaten:
    print(f"Breedtegraad: {breedte}, Lengtegraad: {lengte}")

Net al een list kun je langs een tuple itereren. De eerste uitwerking is wellicht de meest intuïtieve: elke loop neem je het coördinatenpaar (een tuple) en haal je de elementen op met respectievelijk coord[0] en coord[1].

De tweede oplossing maakt gebruik van uitpakken. In elke loop pak je de tuple uit in de variabelen breedte en lengte, zodat je deze direct in je f-string kunt gebruiken.

Overigens werkt uitpakken niet alleen bij tuples, maar bij alle iterables. Wel zie je het vaak bij functies die een tuple (zonder haakjes) teruggeven.