CMD + K

6 min lesing3 videoer

Lister og tupler

En liste er en ordnet, foranderlig samling vi kan indeksere, dele opp og endre med metoder som append og pop. En tuppel ligner, men er uforanderlig. Vi ser hvordan du bygger, gjennomløper og transformerer slike sekvenser.

Læringsmål
  • 01Lage og indeksere lister, og bruke slicing til å hente ut delsekvenser på samme måte som for strenger
  • 02Forklare at lister er foranderlige og tupler uforanderlige, og velge riktig type ut fra om innholdet skal endres
  • 03Bygge opp en liste i en løkke med append, og lese en sporings-tabell som viser hvordan lista vokser per iterasjon
  • 04Bruke sentrale listeoperasjoner (append, pop, sort, index, count, in) og skille dem som endrer lista fra dem som bare gir et svar

En liste er en ordnet samling

Skriv tall = [3, 1, 4, 1, 5], og du har laget en liste: en ordnet samling av verdier i hver sin celle, akkurat som tegnene i en streng. Forskjellen er at en liste kan inneholde hva som helst — tall, strenger, sannhetsverdier, til og med andre lister — og at den kan blandes: ["Ada", 1815, True] er en helt lovlig liste.

Akkurat som med strenger har hvert element en indeks, og tellingen starter på null. tall[0] er 3, tall[1] er 1, og tall[-1] er det siste elementet, 5. Lengden får du med len(tall), som her gir 5. Be om en indeks utenfor lista, og du får en IndexError.

tall30-511-442-313-254-1Hvert element ligger i sin egen celle med en indeks under. Verdien 1 står på både indeks 1 og 3 — det er indeksen, ikke verdien, som peker ut et bestemt element.
FIGLista [3, 1, 4, 1, 5] med indekser

Figuren viser lista [3, 1, 4, 1, 5] med indeksene under hver celle. Legg merke til at to celler kan ha samme verdi — her står 1 på både indeks 1 og indeks 3. Indeksen, ikke verdien, er det som peker ut et bestemt element.

Slicing fungerer på lister på nøyaktig samme måte som på strenger. tall[1:4] gir den nye lista [1, 4, 1] — elementene på indeks 1, 2 og 3, men ikke 4. tall[:2] gir de to første, tall[-2:] gir de to siste, og tall[::-1] gir lista baklengs. Alt du lærte om slicing av strenger overføres direkte.

Lister er foranderlige — i motsetning til strenger

Her skiller listene seg skarpt fra strengene. En liste har mutabilitet: du kan endre den etter at den er laget. tall[0] = 9 bytter ut det første elementet, slik at lista blir [9, 1, 4, 1, 5]. Dette ville krasjet med en streng, men på en liste er det helt vanlig.

Denne forskjellen er verdt å feste seg ved, fordi den får praktiske følger. Når du sender en liste inn i en funksjon og funksjonen endrer den, ser du endringen også utenfor funksjonen — lista deles, den kopieres ikke. Det er kraftig, men også en kilde til overraskelser, så vær bevisst på når du endrer en delt liste.

Å bygge opp og rive ned

To metoder bruker du støtt: append legger til ett element på slutten av lista, og pop fjerner og returnerer det siste elementet (eller elementet på en gitt indeks). Sammen lar de deg vokse og krympe en liste mens programmet kjører:

python
kø = [] kø.append("Ada") # ["Ada"] kø.append("Alan") # ["Ada", "Alan"] først = kø.pop(0) # først = "Ada", kø = ["Alan"]

Merk at append endrer lista på plass og returnerer None — du skal ikke skrive kø = kø.append("Ada"), for da overskriver du lista med None. Dette er motsatt av strengmetodene, som lagde nye strenger. Forskjellen henger sammen med at lister er foranderlige: metodene kan og skal endre originalen.

Det aller vanligste mønsteret i hele programmeringen er å starte med en tom liste og bygge den opp i en løkke. Du så akkumulator-tanken for tall i løkke-kapittelet; her er listevarianten:

python
kvadrater = [] for i in range(1, 6): kvadrater.append(i * i) print(kvadrater) # [1, 4, 9, 16, 25]
for i in range(1, 6): kvadrater.append(i * i)ii * ikvadraterstart[]iter 111[1]iter 224[1, 4]iter 339[1, 4, 9]iter 4416[1, 4, 9, 16]iter 5525[1, 4, 9, 16, 25]For hver runde regnes i * i ut og legges bakerst med append, slik at lista blir ett element lengre per iterasjon.
FIGBygge en liste med append i en løkke

Sporings-tabellen over viser hvordan lista vokser for hver runde i løkka. Følg i-kolonnen og se hvordan i * i regnes ut og legges bakerst, slik at lista blir ett element lengre per iterasjon. Når løkka er ferdig, står hele resultatet klart. Å lese en slik trace i hodet er en av de mest verdifulle ferdighetene du kan trene opp: det er nøyaktig det du gjør når du leter etter en feil i egen kode.

liste-operasjoner

Sentrale listeoperasjoner

python
tall = [3, 1, 4, 1, 5] # Operasjoner som ENDRER lista på plass (returnerer None):tall.append(9)        # [3, 1, 4, 1, 5, 9]tall.insert(0, 2)     # [2, 3, 1, 4, 1, 5, 9]siste = tall.pop()    # siste = 9, tall = [2, 3, 1, 4, 1, 5]tall.remove(1)        # fjerner FØRSTE 1 -> [2, 3, 4, 1, 5]tall.sort()           # [1, 2, 3, 4, 5]tall.reverse()        # [5, 4, 3, 2, 1] # Operasjoner som bare GIR ET SVAR (rører ikke lista):print(len(tall))      # 5print(3 in tall)      # Trueprint(tall.index(4))  # 1  (indeksen til verdien 4)print(tall.count(2))  # 1  (hvor mange ganger 2 forekommer)

Skill mellom metoder som endrer lista på plass og returnerer None (append, insert, pop, remove, sort, reverse) og funksjoner/metoder som bare gir en opplysning (len, in, index, count). Skriv aldri tall = tall.append(...).

Snutten samler de operasjonene du kommer til å bruke oftest. Studer hvilke som endrer lista på plass (append, pop, sort, reverse, remove, insert) og hvilke som bare gir deg en opplysning uten å røre lista (len, in, index, count). Et godt vett-regel: hvis metoden gjør noe med lista, returnerer den som regel None; hvis den spør om noe, returnerer den et svar.

Å løpe gjennom en liste

Som en streng er en liste en sekvens, og du går gjennom den med en for-løkke. Det vanlige er å ta ett element om gangen:

python
navn = ["Ada", "Alan", "Grace"] for n in navn: print(n)

Trenger du indeksen i tillegg til verdien, gir enumerate deg begge uten at du må telle selv:

python
for i, n in enumerate(navn): print(i, n) # 0 Ada, 1 Alan, 2 Grace

En klassisk felle er å endre en liste mens du løper gjennom den — å fjerne elementer i samme løkke som leser dem får løkka til å hoppe over verdier. Tryggest er det å bygge en ny liste med dem du vil beholde, og la originalen være i fred under selve gjennomløpet. Et annet vanlig mønster er å løpe gjennom og samtidig akkumulere et resultat, for eksempel summere alle tallene i en liste eller telle hvor mange som er over en grense.

Python har dessuten en kompakt skrivemåte for å bygge en ny liste ut fra en gammel, kalt listeforståelse: [i * i for i in range(1, 6)] gir [1, 4, 9, 16, 25] på én linje, og gjør nøyaktig det samme som løkka med append over. Du trenger ikke bruke den ennå, men det er greit å kjenne igjen formen når du møter den, for den er svært utbredt i ekte Python-kode.

Når rekkefølgen teller, men ikke endringen: tupler

Noen ganger vil du ha en samling som ikke skal kunne endres. Da bruker du en tuppel, som du skriver med vanlige parenteser: punkt = (3, 4). En tuppel oppfører seg som en liste på alle vis som har med lesing å gjøre — punkt[0] gir 3, slicing og len virker som forventet — men den er uforanderlig, akkurat som en streng. punkt[0] = 9 gir en TypeError.

Hvorfor velge noe du ikke kan endre? Av samme grunner som med strenger. Uforanderlighet signaliserer til den som leser koden at disse verdiene hører sammen og ikke skal tukles med — et koordinatpar, en dato som (år, måned, dag), en returverdi med flere deler. En tuppel kan dessuten brukes som nøkkel i en dictionary, noe en liste ikke kan, nettopp fordi den ligger fast.

En elegant detalj er utpakking: x, y = punkt plukker de to verdiene rett ut i hver sin variabel. Det er dette som skjer bak kulissene når en funksjon ser ut til å returnere «flere verdier» — den returnerer egentlig en tuppel, og du pakker den opp på mottakersiden. Det samme trikset lar deg bytte om to variabler på én linje: a, b = b, a, uten en midlertidig hjelpevariabel.

Vær oppmerksom på én syntaktisk snublestein: en tuppel med ett element må ha et etterfølgende komma, (5,), ikke (5). Uten kommaet leser Python (5) som bare tallet 5 i parentes. Kommaet er det som faktisk lager tuppelen — parentesene er stort sett bare for lesbarhetens skyld, og 5, 6 er en gyldig tuppel også uten dem.

Oppsummert: liste eller tuppel?

Velg liste når samlingen skal vokse, krympe eller endres underveis — handlekurver, måleserier, alt du bygger opp i en løkke. Velg tuppel når innholdet er fast og hører sammen som en enhet — et punkt, en post, et par av sammenhørende verdier. Begge er ordnede og indekserte, begge støtter slicing og in, og begge kan løpes gjennom med en for-løkke. Det avgjørende skillet er det ene ordet du nå kjenner godt: kan den endres eller ikke?

Mine notater

Skriv egne notater for dette kapittelet. De lagres automatisk og dukker opp i «Mine notater»-oversikten paa fag-siden.

Laster…