Ga naar hoofdinhoud

12 Tuples

Bij het lopen door een dictionary zag je al for sleutel, waarde in ...: twee namen die samen één paar opvangen. Dat paar heeft een naam. Kijk wat hier gebeurt:

punt = (3, 5)

print(punt[0]) # 3
print(punt[1]) # 5

punt is een tuple: een vast rijtje waardes dat bij elkaar hoort, tussen ronde haakjes. Opvragen werkt met een index, net als bij een lijst.

punt = (3, 5)
punt[0] = 4
print(punt)
Voorspel
Wat zet dit programma op het scherm?
Kies wat jij denkt. Bij het goede antwoord zie je de uitleg.

Uitpakken​

De waardes van een tuple kun je in één regel in losse variabelen zetten. Dat heet unpacking:

punt = (3, 5)
x, y = punt

print(f"x is {x}, y is {y}") # x is 3, y is 5

Het aantal namen links moet gelijk zijn aan het aantal waardes in de tuple, anders krijg je een ValueError. Dit is precies wat er in Door een dictionary lopen gebeurde bij for sleutel, waarde in leerling.items(): elke ronde levert .items() een tuple, die je meteen uitpakt in twee namen.

Twee waardes returnen​

Een functie kan maar één ding teruggeven, maar dat ene ding mag een tuple zijn. Zo geef je toch twee waardes terug:

def deel_met_rest(getal, deler):
return getal // deler, getal % deler

heel, rest = deel_met_rest(17, 5)
print(f"{heel} keer, rest {rest}") # 3 keer, rest 2

Bij return a, b maakt Python vanzelf een tuple, ook zonder haakjes. De aanroeper pakt hem direct uit. Wat // en % doen, staat in Delen met rest.

De swap​

Twee variabelen wisselen kan met een hulpvariabele, maar met een tuple gaat het in één regel:

a = 1
b = 99

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

Python maakt eerst rechts de tuple (99, 1) en pakt die daarna links uit. Geen waarde gaat verloren, want de tuple bestaat al voordat het overschrijven begint.

Tuple of lijst?​

lijsttuple
Aanpassen na het makenjanee
Lengtegroeit en krimptligt vast
Gebruikverzameling losse itemswaardes die bij elkaar horen

Vuistregel: een rij dingen van hetzelfde soort (namen, getallen) is een lijst; een klein groepje waardes dat samen één ding beschrijft (een coördinaat, een naam-met-score) is een tuple.

Er gaat iets mis​

Een tuple veranderen

punt = (3, 5)
punt[0] = 4

Uitvoer:

TypeError: 'tuple' object does not support item assignment

Een tuple ligt vast. Moet de waarde veranderen, maak dan een nieuwe tuple: punt = (4, 5). Of kies een lijst als je de waardes vaak aanpast.

Te veel waardes om uit te pakken

x, y = (1, 2, 3)

Uitvoer:

ValueError: too many values to unpack (expected 2)

Links staan twee namen, rechts drie waardes. Zet links evenveel namen als er waardes zijn: x, y, z = (1, 2, 3).


Opdracht 12.1: Coördinaat uitpakken​

Hieronder staat een coördinaat. Pak hem uit in x en y en print de regel hieronder.

Verwachte uitvoer:

Het punt ligt op x=4 en y=7
punt = (4, 7)

# Schrijf hier je code
Klik hier voor een tip.

x, y = punt zet de eerste waarde in x en de tweede in y. Gebruik daarna een f-string.

Klik hier voor de oplossing.
punt = (4, 7)

x, y = punt
print(f"Het punt ligt op x={x} en y={y}")
punt = (4, 7)

x, y = punt
print(f"Het punt ligt op x={x} en y={y}")

Opdracht 12.2: Kleinste en grootste tegelijk​

Schrijf een functie kleinste_en_grootste(lijst) die een tuple teruggeeft met eerst de kleinste en dan de grootste waarde. Gebruik min() en max().

Verwachte uitvoer:

kleinste: 2, grootste: 9
getallen = [5, 2, 8, 9, 3]

# Schrijf hier je code
Klik hier voor een tip.

return min(lijst), max(lijst) geeft beide terug in één tuple. Vang ze op met klein, groot = kleinste_en_grootste(getallen).

Klik hier voor de oplossing.
getallen = [5, 2, 8, 9, 3]

def kleinste_en_grootste(lijst):
return min(lijst), max(lijst)

klein, groot = kleinste_en_grootste(getallen)
print(f"kleinste: {klein}, grootste: {groot}")
getallen = [5, 2, 8, 9, 3]

def kleinste_en_grootste(lijst):
    return min(lijst), max(lijst)

klein, groot = kleinste_en_grootste(getallen)
print(f"kleinste: {klein}, grootste: {groot}")

Opdracht 12.3: Scorelijst (uitdaging)​

Hieronder staat een lijst met (naam, score)-tuples. Print voor elke speler een regel, en wissel daarna de inhoud van eerste en laatste zonder hulpvariabele.

Verwachte uitvoer:

Sara heeft 12 punten
Alex heeft 9 punten
Maria heeft 15 punten
eerste: Maria, laatste: Sara
scores = [("Sara", 12), ("Alex", 9), ("Maria", 15)]
eerste = "Sara"
laatste = "Maria"

# Schrijf hier je code
Klik hier voor een tip.

In de loop pak je elke tuple direct uit: for naam, punten in scores:. De wissel is één regel met een komma aan beide kanten.

Klik hier voor de oplossing.
scores = [("Sara", 12), ("Alex", 9), ("Maria", 15)]
eerste = "Sara"
laatste = "Maria"

for naam, punten in scores:
print(f"{naam} heeft {punten} punten")

eerste, laatste = laatste, eerste
print(f"eerste: {eerste}, laatste: {laatste}")
scores = [("Sara", 12), ("Alex", 9), ("Maria", 15)]
eerste = "Sara"
laatste = "Maria"

for naam, punten in scores:
    print(f"{naam} heeft {punten} punten")

eerste, laatste = laatste, eerste
print(f"eerste: {eerste}, laatste: {laatste}")

En nu?​

Nog één datatype: in de volgende les leer je de set, een verzameling zonder dubbelen, handig om bij te houden wat je al gehad hebt.

Waar kom je dit later weer tegen?

Max-en-min geeft (klein, groot) terug, bij knapsack is elk item een tuple (waarde, gewicht), en de zetten van Hanoi zijn tuples (bron, doel).