Lister#
Læringsutbytte
Etter å ha arbeidet med dette temaet, skal du kunne:
opprette og modifisere lister
gjøre rede for noen vanlige listeoperasjoner (NB: Du trenger ikke pugge operasjonene!)
hente ut enkeltelementer og deler av lister ved hjelp av indekser
bruke lister til å organisere kjemiske data
skille mellom å kombinere lister og å utføre regneoperasjoner på verdiene i dem
Når vi trenger å lagre flere verdier i samme variabel, kan vi benytte lister. En liste er en ordnet samling av verdier. Det kan for eksempel være navn på grunnstoffer, temperaturer fra et eksperiment eller absorbansverdier målt ved ulike bølgelengder.
Lister i Python markeres med hakeparenteser ([]), og elementene skilles med komma:
grunnstoffer = ["hydrogen", "helium", "litium", "beryllium", "bor"]
atomnummer = [1, 2, 3, 4, 5]
temperaturer = [20.0, 25.0, 30.0, 35.0]
Rekkefølgen på elementene bevares. I lista grunnstoffer er «hydrogen» det første elementet og «bor» det siste. En liste kan inneholde både tall, tekst og andre datatyper, men når lista representerer måledata, er det som regel ryddigst at alle verdiene har samme betydning og enhet.
Liste
En liste er en ordnet samling av verdier som er lagret i én variabel. Lister kan endres etter at de er opprettet.
Legge til og fjerne elementer#
Vi kan gjøre ulike listeoperasjoner, som å legge til, fjerne og flytte på elementer. Her bruker vi en liste med grunnstoffer som eksempel:
grunnstoffer = [] # Lager ei tom liste
edelgasser = ["helium", "neon", "argon"] # Lager ei liste med edelgasser
grunnstoffer.append("litium") # Legger til ett element
grunnstoffer.extend(edelgasser) # Legger til alle elementene fra edelgasser
grunnstoffer.remove("neon") # Fjerner elementet med verdien "neon"
fjernet_grunnstoff = grunnstoffer.pop(1) # Fjerner elementet med indeks 1
grunnstoffer.reverse() # Reverserer rekkefølgen
print(grunnstoffer)
print("Fjernet grunnstoff:", fjernet_grunnstoff)
Underveisoppgave
Hva slags output gir programmet ovenfor? Prøv å følge endringene i lista uten datamaskin. Test deretter programmet og se om du hadde rett.
Løsningsforslag
Etter append og extend er lista ["litium", "helium", "neon", "argon"]. Først fjernes «neon» ved hjelp av verdien. Deretter fjerner pop(1) elementet med indeks 1, som er «helium», og lagrer det i variabelen fjernet_grunnstoff. Til slutt reverseres lista. Programmet skriver derfor ut:
['argon', 'litium']
Fjernet grunnstoff: helium
Legg merke til forskjellen mellom remove og pop: remove bruker selve verdien vi vil fjerne, mens pop bruker indeksen. Hvis den samme verdien finnes flere ganger, fjerner remove den første forekomsten.
Indekser#
Plassnummeret til et element i lista kaller vi en indeks. Indeksen angis i hakeparenteser. Vi kan også finne lengden av lista og søke etter indeksen til en bestemt verdi:
grunnstoffer = ["H", "C", "N", "O", "F", "Na", "Mg", "Cl", "Ar"]
atomnummer = [1, 6, 7, 8, 9, 11, 12, 17, 18]
print("Antall grunnstoffer:", len(grunnstoffer))
print("Indeksen til Cl:", grunnstoffer.index("Cl"))
print("Atomnummeret til Cl:", atomnummer[7])
Underveisoppgave
Hva skriver programmet ut? Hvorfor er indeksen til "Cl" lik 7 når klor er det åttende grunnstoffet i lista?
Du kan kjøre og endre indeksprogrammet i editoren nedenfor.
Men vent nå litt! Lista inneholder ni elementer, og klor står på plass nummer 8 dersom vi teller på vanlig måte. Indeksen er likevel 7. Det er fordi indekser i Python, og mange andre programmeringsspråk, starter på 0. Indeksen til det første elementet er 0, mens indeksen til det siste elementet i denne lista er 8. Ei liste med \(n\) elementer har derfor indekser fra \(0\) til \(n-1\).
De to listene ovenfor er parallelle lister: Elementer med samme indeks hører sammen. Symbolet "Cl" har indeks 7 i lista grunnstoffer, og atomnummeret til klor ligger derfor på indeks 7 i lista atomnummer. Denne ideen kan brukes til å koble sammen for eksempel bølgelengder og absorbansverdier.
Hente ut deler av ei liste#
Vi trenger ikke behandle hele lista hver gang vi vil bruke noen av elementene. En enkelt indeks henter ett element, mens kolon brukes til å hente et intervall, også kalt et utsnitt eller en slice:
absorbanser = [0.12, 0.25, 0.37, 0.49, 0.61]
A = absorbanser[2] # Elementet med indeks 2
B = absorbanser[1:3] # Fra og med indeks 1 til, men ikke med, indeks 3
C = absorbanser[2:] # Fra og med indeks 2 til slutten
D = absorbanser[:2] # Fra starten til, men ikke med, indeks 2
E = absorbanser[-1] # Det siste elementet
F = absorbanser[-2] # Det nest siste elementet
Underveisoppgave
Hvilken verdi får variablene A, B, C, D, E og F ovenfor?
Løsningsforslag
Indekser angir plasseringen i lista. Dersom indeksen er negativ, teller vi baklengs fra slutten. Kolon kan leses som «fra og med, men ikke til og med». Utsnittet [1:3] inneholder derfor elementene med indeks 1 og 2, men ikke elementet med indeks 3.
Når det ikke står noe foran kolon, begynner utsnittet med det første elementet. Når det ikke står noe etter kolon, fortsetter det til slutten. Vi får derfor:
A: 0.37
B: [0.25, 0.37]
C: [0.37, 0.49, 0.61]
D: [0.12, 0.25]
E: 0.61
F: 0.49
Kombinere og undersøke lister#
Det finnes ofte flere måter å gjøre ting på. La oss se på et eksempel der vi kombinerer to temperaturserier og endrer den nye lista:
temperatur_serie1 = [20.0, 25.0, 30.0]
temperatur_serie2 = [35.0, 40.0]
temperaturer = temperatur_serie1 + temperatur_serie2
temperaturer.append(45.0)
temperaturer.remove(30.0)
print(temperaturer)
print("Finnes 30.0 i lista?", 30.0 in temperaturer)
Underveisoppgave
Forklar hva som skjer i programmet ovenfor. Hva blir skrevet ut? Utvid programmet slik at det også skriver ut den siste temperaturen og alle temperaturene bortsett fra den første.
Løsningsforslag
Operatoren + kombinerer de to listene. Deretter legges 45,0 til, mens 30,0 fjernes. Programmet skriver ut lista [20.0, 25.0, 35.0, 40.0, 45.0] og deretter False, siden 30,0 ikke lenger finnes i lista.
De to ekstra utskriftene kan skrives slik:
print(temperaturer[-1])
print(temperaturer[1:])
Når vi legger sammen lister med +, kombinerer vi listene. Vi adderer ikke tallene element for element:
[1, 2] + [3, 4] # Gir [1, 2, 3, 4], ikke [4, 6]
Senere skal vi bruke spesielle NumPy-tabeller (såkalte arrayer) når vi vil utføre den samme matematiske operasjonen på mange måleverdier samtidig.
Noen nyttige listeoperasjoner#
Nedenfor ser du noen flere muligheter vi har med lister. Du trenger ikke pugge alle operasjonene. Det viktigste er at du kan lese koden, forstå hva slags operasjon du trenger og slå opp kommandoene når det er nødvendig.
Operasjon |
Forklaring |
Eksempel |
|---|---|---|
|
Antall elementer |
|
|
Summen av alle tallene |
|
|
Minste verdi |
|
|
Største verdi |
|
|
Undersøker om en verdi finnes |
|
|
Indeksen til første forekomst |
|
|
Antall forekomster |
|
|
Sorterer og endrer den opprinnelige lista |
|
Lister kan endres
Hvis vi skriver kopi = målinger, lager vi ikke en uavhengig kopi. Begge variabelnavnene peker til den samme lista, og en endring gjennom det ene navnet blir synlig gjennom det andre. Bruk kopi = målinger.copy() dersom du trenger en egen liste som kan endres uavhengig av originalen.
Oppgaver#
Oppgave 2.1
Forklar for hvert program hvorfor det gir den oppgitte outputen.
atommasser = [1.008, 12.01, 14.01, 16.00]
molar_masse_vann = 2*atommasser[0] + atommasser[3]
print(round(molar_masse_vann, 3))
Output: 18.016
grunnstoffer = ["H", "C", "N", "O", "F"]
utvalg = grunnstoffer[:3]
grunnstoffer.pop(1)
utvalg.reverse()
del utvalg[2]
grunnstoffer += utvalg
print(grunnstoffer)
Output: ['H', 'N', 'O', 'F', 'N', 'C']
Løsningsforslag
atommasser[0]henter atommassen til hydrogen, mensatommasser[3]henter atommassen til oksygen. Vann inneholder to hydrogenatomer og ett oksygenatom. Den molare massen blir derfor \(2\cdot1{,}008+16{,}00=18{,}016\) g/mol.Vi kan beskrive programflyten steg for steg:
grunnstoffer[:3]girutvalg = ["H", "C", "N"].grunnstoffer.pop(1)fjerner elementet med indeks 1, altså"C". Nå ergrunnstoffer = ["H", "N", "O", "F"].utvalg.reverse()girutvalg = ["N", "C", "H"].del utvalg[2]fjerner"H", slik atutvalg = ["N", "C"].grunnstoffer += utvalgkombinerer listene og gir["H", "N", "O", "F", "N", "C"].
Oppgave 2.2
Du får ei liste med symbolene til de elleve første grunnstoffene:
grunnstoffer = ["H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na"]
Lag ei ny liste ved å hente elementer og utsnitt fra grunnstoffer. Den nye lista skal inneholde grunnstoffene som forekommer i aminosyren glysin:
['H', 'C', 'N', 'O']
Løsningsforslag
grunnstoffer = ["H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na"]
utvalgte_grunnstoffer = grunnstoffer[:1] + grunnstoffer[5:8]
print(utvalgte_grunnstoffer)
Oppgave 2.3
Skriv om linja som endrer lista atomer, slik at i1 og i2 får forskjellige verdier.
atomer = ["H", "C", "O", "C", "H", "O"]
i1 = atomer.index("O")
print("i1 =", i1)
del atomer[5]
i2 = atomer.index("O")
print("i2 =", i2)
Løsningsforslag
Den første forekomsten av "O" har indeks 2. I det opprinnelige programmet fjerner vi den siste forekomsten, slik at den første fortsatt har indeks 2. Vi må i stedet fjerne den første forekomsten:
atomer = ["H", "C", "O", "C", "H", "O"]
i1 = atomer.index("O")
print("i1 =", i1)
del atomer[2]
i2 = atomer.index("O")
print("i2 =", i2)
Etter at den første forekomsten er fjernet, har den gjenværende "O" indeks 4. Vi får derfor i1 = 2 og i2 = 4.
Oppgave 2.4 – titreringsdata
Fire paralleller i en titrering ga følgende forbruk av titrant:
titreringsvolum = [24.95, 25.10, 25.05, 24.90] # mL
Bruk sum, len, min og max til å beregne gjennomsnittsvolumet og variasjonsbredden, altså forskjellen mellom største og minste verdi. Skriv ut begge resultatene med to desimaler.
Løsningsforslag
titreringsvolum = [24.95, 25.10, 25.05, 24.90] # mL
gjennomsnitt = sum(titreringsvolum)/len(titreringsvolum)
variasjonsbredde = max(titreringsvolum) - min(titreringsvolum)
print(f"Gjennomsnittsvolum: {gjennomsnitt:.2f} mL")
print(f"Variasjonsbredde: {variasjonsbredde:.2f} mL")
Oppgave 2.5 – finn \(\lambda_{\mathrm{maks}}\)
Et absorpsjonsspekter er lagret i to parallelle lister. Absorbansen på en bestemt indeks er målt ved bølgelengden på den samme indeksen:
bolgelengder = [400, 450, 500, 550, 600] # nm
absorbanser = [0.12, 0.35, 0.82, 0.46, 0.18]
Bruk max og index til å finne den største absorbansen. Bruk deretter indeksen til å finne bølgelengden der absorbansen er størst. Lagre resultatet i variabelen lambda_maks og skriv ut en svarsetning.
Løsningsforslag
bolgelengder = [400, 450, 500, 550, 600] # nm
absorbanser = [0.12, 0.35, 0.82, 0.46, 0.18]
maks_absorbans = max(absorbanser)
indeks_maks = absorbanser.index(maks_absorbans)
lambda_maks = bolgelengder[indeks_maks]
print(f"Størst absorbans er {maks_absorbans} ved {lambda_maks} nm.")
Lister er nyttige når vi skal samle og organisere verdier. I senere kapitler skal vi bruke NumPy og pandas til å utføre mer omfattende beregninger og analyser på kjemiske datasett.
Video#
Se videoen nedenfor for en innføring eller repetisjon til lister.