Du er ikke logget inn. Så lenge du ikke er logget inn går du glipp av muligheten for å holde styr på din egen progresjon.

Logg inn

Valgte tags:

Filtrering:

Skriv ut:

Comprehension 6: ordbøker

Gitt følgende liste:

gammel_liste = ["vinter","iskrem","bade","grillings","ski"]

a) Lag ei ordbok hvor hvert ord er nøkkelverdien, og innholdsverdien er hvor mange ganger ordet inneholder bokstaven "i".

b) Lag ei ordbok hvor hvert ord er nøkkelverdien, og innholdsverdien er ei liste av tegnene i ordet (F.eks: "kake" blir {'kake':['k','a','k','e']}).

Gitt følgende liste med tupler:

gammel_liste2 = [('Hvorfor', 'ADV'), ('gidder', 'VT'), ('vi', 'PRON'),
('dette', 'PRON'), ('?', 'SYM')]

c) Lag ei ordbok der ordformen er nøkkelverdi og ordklassen er innholdsverdi.

d) Gjør som i c), men utelat alle ord av ordklassen SYM.

Vis løsningsforslag

a)

{x:x.count("i") for x in gammel_liste}

b)

{x:list(x) for x in gammel_liste}

c)

{x[0]:x[1] for x in gammel_liste2}

d)

{x[0]:x[1] for x in gammel_liste2 if x[1] != "SYM"}

Funksjoner 0: Introduksjoner

En subrutine er en måte å styre kodeflyten på i et program. I python bruker vi ordet "def", fra "define", for å definere subrutiner. Noen ganger skiller man mellom prosedyrer, funksjoner og metoder.
En prosedyre er da en subrutine som ikke har en eksplisitt returverdi, mens en funksjon har en eksplisitt returverdi. Metoder hører til en klasse, og kalles metoder uavhengig av returverdien. Alle subrutiner kan ta ha parametre, uten at det påvirker navngivningen. Metoder blir ikke behandlet her.

En subrutine kan se slik ut:

def skrivhei():
    print("Hei!")

Denne prosedyren, skrivhei(), er en prosedyre fordi vi ikke har brukt kodeordet "return" (mer om det snart!). Den skriver ut en melding til brukeren. Den gjør altså det samme som å bare skrive print("Hei!"), men vi kan kalle på den når vi vil. Vi kaller på en prosedyre, funksjon eller metode ved å skrive paranteser under. Hvis ingen parametre er nødvendige så er parantesene tomme.

Vi kan kalle på prosedyren skrivhei():

skrivhei()

Da får vi utskriften:

>>>Hei!

En prosedyre kan ta parametre. Vi lager en ny prosedyre, skrivhei2(), som tar inn navnet til brukeren den skal si hei til. navn er da parameteren som holder på navnet. Når vi definerer prosedyren vet vi ikke ennå akkurat hva slags verdi den har, men vi bør ha det klart for oss hva slags type det skal være, slik at vi ikke får feil i programmet. I dette tilfellet antar vi at navn er en streng.

def skrivhei2(navn):
    print("Hei,",navn,"!")

Så langt har vi bare skrevet ut ting i prosedyrene. Prosedyrer som dette kan skrive ut ting, ta inn info, og endre verdier, men vi kan ikke få noe tilbake. For å lage subrutiner som gir oss noe, et resultat, så må vi bruke ordet return. Vi får da en funksjon, og sier at den returnerer noe. Det som returneres er returverdien til funksjonen. Funksjoner har stort sett parametre. Merk at informatikk-definisjonen av funksjoner i dette tilfellet er mindre streng enn definisjonen du kanskje kjenner igjen fra matematikken. Den forskjellen er ikke viktig i dette tilfellet.

Vi lager en funksjon adder(x,y) som tar to tall, x og y, og legger dem sammen. Summen blir returnert.

def adder(x,y):
    summen = x + y
    return summen

Man kan også forkorte koden, siden vi ikke bruker variabelen "summen" til noe annet her:

def adder(x,y):
    return x + y

Nå kan vi sende med to argumenter og kalle på funksjonen. Argumenter er det vi kaller de faktiske verdiene vi gir parametrene i funksjonen. I funksjonen adder(x,y) er x og y parametre. I funksjonskallet under er 1 og 2 argumenter.

Når en funksjon returnerer noe så er ikke resultatet umiddelbart synlig. Det er ikke noe utskrift. Vi må skrive til terminalen eller lignende uavhengig av funksjonen:

Dette gir altså ingen utskrift:

adder(1,2)

Mens dette gjør det:

print(adder(1,2))

Utskrift:

3

Et funksjonskall blir evaluert til returverdien sin. Det er veldig nyttig. Vi kan altså skrive:

mitt_tall = adder(1,2) + adder(3,4)

Eller så kan vi ta den helt ut og skrive kode som er vanskelig å lese, men som kjører:

mitt_tall = adder(adder(1,2),adder(3,4))

Verdien til mitt_tall blir i begge tilfeller 10.

Funksjoner 1: Lambda-utrykk og anonyme funksjoner (intro)

Du er kanskje vant med å lage funksjoner som kan se slik ut nå:

def adder(x,y):
    return x + y

Funksjonen har et navn "adder", to parametre, og en returverdi som er summen av de to tallene.

Ofte ser vi kun funksjonene når vi kaller på dem. Men! Funksjonsnavn er egentlig som alle andre variabler. Vi kan definere tre funksjoner og putte dem i ei liste:

def adder(x,y):
    return x + y

def subtraher(x,y):
    return x - y

def multipliser(x,y):
    return x * y

funksjoner = [adder,subtraher,multipliser]    

Da kan vi skrive ting som:

tall = funksjoner[1](10,4)
print(tall)

Utskrift:

6

Kult! Dette er faktisk en såpass vanlig ting, at man har en spesiell måte å skrive funksjoner på til dette formålet. Det gjør at vi slipper å måtte definere alle tingene hver gang, så vi sparer både tid og kodelinjer. Disse funksjonene kalles anonyme funksjoner, eller lambda-uttrykk. De er lånt fra funksjonell programmering, som mange andre ting som er vanlige i mange språk i dag.

Lambda-uttrykk bruker kodeordet "lambda".

De tre funksjonene over kan skrives rett i lista slik:

[lambda x,y: x+y,lambda x,y:x-y,lambda x,y:x*y]

Vi starter altså alle funksjonene med ordet "lambda". Så kommer parameterne x,y. Vi kan legge til så mange vi vil, som vanlig. Etter parameterne er det ett kolon ":", før vi skriver returverdien.

Det er praktisk å kunne ha funksjoner i lister og ordbøker, men det er spesielt som argumenter til andre funksjoner at lambda-uttrykk virkelig er interessante og mye brukt.

Vi kan skrive en funksjon som utfører en matematisk operasjon på alle elementene og lager ei ny liste:

def alle(liste,funksjon):
    nyliste = []
    for e in liste:
        nyliste.append(funksjon(e))

For eksempel, si vi vil kalle på funksjonen over med en funksjon som opphøyer tallene i 3:

liste = [1,2,3,4,5]
print(alle(liste,lambda x: x**3))

Da får vi:

[1, 8, 27, 64, 125]

Noen funksjoner krever at et av argumentene er en funksjon, slik som defaultdict. Da er det greit å bruke lambda-funksjoner.

Funksjoner 2: Lambda-uttrykk

I IN1140 er det hovedsakelig som input til defaultdict at vi bruker lambda-uttrykk, men i disse oppgavene kan du lære å bruke dem litt mer.

Oppgave 1

Skriv en funksjon som tar inn en annen funksjon og ei liste. Kall den "alle". Funksjonen du skriver skal returnere ei ny liste der hvert element er resultatet av å kalle funksjonen som blir sendt inn som argument på hvert element i lista. For eksempel kan vi ha ei liste lista = [1,2,3], og en funksjon pluss1 som legger til 1 til et tall (den tar bare inn ett tall om gangen). alle(pluss1,liste) gir oss da lista [2,3,4]. Det er altså funksjonen alle som skal sørge for at den anonyme funksjonen brukes på hvert element.

Så skal du kalle på funksjonen din med tre anonyme funksjoner (se under) ved å bruke lambda-uttrykk når du kaller på den.

Lista du skal bruke er:

liste = [4,6,8,10,12,14,16]

Skriv ut alle resultatene til terminalen.

a) Bruk en anonym funksjon som ganger et tall med 8
b) Bruk en anonym funksjon som opphøyer et tall i andre
c) Bruk en anonym funksjon som gjør om tallet til en streng
d) Bruk en anonym funksjon som repeterer sifrene i tallet (f.eks: 42 -> 4242)

Oppgave 2

Lag en ny funksjon som igjen skal ta inn en annen funksjon og ei liste. La funksjonen hete "noen". Denne nye funksjonen skal også lage ei ny liste, men denne gangen skal den anonyme funksjonen returnere en boolsk verdi som bestemmer om elementet skal med i den nye lista eller ikke. Funksjonen noen returnerer altså en delmengde av den opprinnelige lista, basert på den anonyme funksjonen.

Bruk denne lista:

liste2 = ['datamaskin', 'kalkulator', 'telefaks', 'telefon', 'fonologi', 'logisk', 'logo', 'telehiv', 'brunost']

Skriv ut alle resultatene til terminalen.

a) Bruk en anonym funksjon som returnerer True hvis ordet inneholder "fon".
b) Bruk en anonym funksjon som returnerer True hvis ordet ikke inneholder "log".
c) Bruk en anonym funksjon som returnerer True hvis den første bokstaven i ordet er "t".
d) Bruk en anonym funksjon som returnerer True hvis ordet er lengre enn 7 bokstaver.

Vis løsningsforslag

Løsningsforslag:

Oppgave 1

def alle(funksjon, liste):
    ny = []
    for e in liste:
        ny.append(funksjon(e))
    return ny
print(alle(lambda x: x * 8,liste))
print(alle(lambda x: x ** 2,liste))
print(alle(lambda x: str(x),liste))
print(alle(lambda x: str(x) + str(x),liste))

Disse oppgavene er ikke nødvendigvis den mest effektive måten å gjøre dette på. Et godt eksempel er oppgaven der vi kaller på str-funksjonen inne i den anonyme funksjonen. Siden str er en funksjon i seg selv (samme med int, list,dict, osv.), så kan vi sende den som den er:

print(alle(str,liste))

Det er det vi ofte gjør når vi bruker defaultdict.

Utskrift:

[32, 48, 64, 80, 96, 112, 128]
[16, 36, 64, 100, 144, 196, 256]
['4', '6', '8', '10', '12', '14', '16']
['44', '66', '88', '1010', '1212', '1414', '1616']

Oppgave 2

def noen(funksjon, liste):
    ny = []
    for e in liste:
        if funksjon(e):
            ny.append(e)
    return ny

Funksjonskall:

print(noen(lambda x: "fon" in x,liste2))
print(noen(lambda x: "log" not in x,liste2))
print(noen(lambda x: x[0] == "t",liste2))
print(noen(lambda x: len(x) > 7,liste2))

Hvis du hadde True if først i de anonyme funksjonene her så gir det det samme resultatet, men det er ikke nødvendig, siden de boolske uttrykkene alene gir oss True/False.

Utskrift:

['telefon', 'fonologi']
['datamaskin', 'kalkulator', 'telefaks', 'telefon', 'telehiv', 'brunost']
['telefaks', 'telefon', 'telehiv']
['datamaskin', 'kalkulator', 'telefaks', 'fonologi']

Det dere egentlig har laget her er en mapping-funksjon (alle) og en filtering-funksjon (noen). Mapping-funksjonen kjører samme operasjon i en mengde, og filter "filtrerer ut" elementene vi vil ha/ikke ha. Disse funksjonene er i seg selv ikke i IN1140-pensum, men dere kommer til å møte på dem senere, og de er enkle nok å øve på :D Lykke til videre med oppgaveløsing!

Lese fra fil 0: introduksjon

Å lese fra ei fil, og å skrive til ei fil, er ting vi ikke kommer utenom. Tekstene vi jobber med er ofte veldig store, og selv om vi kan kopiere og lime inn mindre strenger rett inn i programmet vårt, blir det fort knotete. Filer lar oss organisere data på mange måter, og filendelsene sier som regel noe om hva slags struktur man kan forvente, som i .txt, .csv, .tsv og .json. Python har støtte for å gjøre det enklere å lese visse typer filer, men stort sett alle filer kan leses inn uten å måtte bruke noen ekstrabiblioteker.

Når vi leser ei fil bruker vi funksjonen open(). Som med mange andre funksjoner, kan vi legge til flere argumenter etter behov.

Helt grunnleggende bruk er slik:

fila = open("minfil.txt")
teksten = fila.read()
fila.close()

I første linje åpner vi fila som et filobjekt. Et filobjekt er en spesiell datatype som vi kan gjøre forskjellige ting med.
På linje to bruker vi metoden .read() på filobjektet. Denne metoden gir oss hele filobjektet som en streng.
Til slutt lukker vi fila. Dette er viktig for å unngå at man prøver å åpne fila i to forskjellige programmer samtidig.

I eksempelet over vet Python at vi vil lese inn fila, det er egentlig det samme som å skrive:

fila = open("minfil.txt","r")

"r" står for read, og er underforstått. Hvis vi skriver "w" så åpner vi for at vi kan skrive til ei fil, og hvis vi bruker "a" så kan vi legge noe til i ei fil. Vi kommer tilbake til skriving seinere.

Vi kan også spesifisere encoding. Det meste passer med utf-8, som er en ny og fin standard, men i noen tilfeller må man spesifisere andre typer. Vi går ikke inn på de spesielle typene her.

fila = open("minfil.txt","r",encoding="utf-8")

Vi bruker nøkkelordargumentet "encoding" for å spesifisere det.

Når vi har lest inn ei fil, er det flere måter vi kan få tak i teksten på. Måten vi gjør det på avhenger av behovet vårt. I eksemplene under brukes teksten "testtekst.txt"

En måte er å gjøre som over, å bruke .read(). Hvis vi vil ha hver setning i en tekst, kan vi så splitte denne fila senere.

```python
fila = open("minfil.txt")
teksten = fila.read()
setninger = teksten.split("\n")
fila.close()

En annen måte er å bruke metoden .readlines()

```python
Gå på plasser der det er litt lysåpen skog, der sola kommer ned på bakken, og der det er litt tørt.
Ikke i tett skog.
Hvis du har en tursti eller ei bymark i nærheten, skal du ikke gå langt for å finne blåbærlyngen.
I lavlandet i sør er sesongen på hell, men i høyden og lenger nord er det fortsatt tid igjen.

['Gå på plasser der det er litt lysåpen skog, der sola kommer ned på bakken, og der det er litt tørt.', 'Ikke i tett skog.', 'Hvis du har en tursti eller ei bymark i nærheten, skal du ikke gå langt for å finne blåbærlyngen.', 'I lavlandet i sør er sesongen på hell, men i høyden og lenger nord er det fortsatt tid igjen.', '']

Vi kan også rett og slett iterere over filobjektet:

fila = open("mini.txt","r",encoding="utf-8")

for linje in fila:
    print(linje)
fila.close()
Gå på plasser der det er litt lysåpen skog, der sola kommer ned på bakken, og der det er litt tørt.

Ikke i tett skog.

Hvis du har en tursti eller ei bymark i nærheten, skal du ikke gå langt for å finne blåbærlyngen.

I lavlandet i sør er sesongen på hell, men i høyden og lenger nord er det fortsatt tid igjen.

Vi kan også bruke metoden readlines() og .readline() legg merke til flertallsendelsen. .readline() leser én og én linje, og hver gang du kaller på readline() så får du neste setning.

Koden under gir lik utskrift som over:

fila = open("mini.txt","r",encoding="utf-8")

for linje in fila.readlines():
    print(linje)
fila.close()

Men en forskjell mellom å bruke .readlines() og å iterere gjennom filobjektet, er at vi kan bruke .readlines() til å lagre linjene i en annen variabel. Filobjektet er en iterator, en datatype som kun kan kalles på én gang. Vi kan undersøke dette ved å bruke type(). Å gå igjennom selve filobjektet kan være lurt hvis vi har med veldig store filer å gjøre.

fila = open("mini.txt","r",encoding="utf-8")

linjer = fila.readlines()
print(type(linjer))

fila.close()

Gir utskriften:

<class 'list'>

readline() er mer nyttig hvis vi vil behandle ett og ett element. Vi kan bruke den sammen med en while-løkke og la den kjøre helt til elementet er en tom streng, som viser at vi har kommet til slutten av dokumentet. Utskriften er lik som i de andre tilfellene.

fila = open("mini.txt","r",encoding="utf-8")

neste = fila.readline()
while neste != "":
    print(neste)
    neste = fila.readline()

fila.close()

Å skrive til fil er ganske likt. Vi må åpne og lukke fila vi vil skrive. Hvis vi har åpnet fila med "w" så vil det vi skriver overskrive hele fila hver gang. Hvis vi har åpnet fila med "a" så vil det vi skriver legges til slutten av fila. I begge tilfeller bruker vi metoden .write() på filobjektet. .write() tar en streng. Vi må huske å lukke filen i dette tilfellet også. Hvis vi skriver én og én linje, for eksempel gjennom en for-løkke, så må vi i noen tilfeller huske å legge til et ekstra linjeskift for at teksten skal komme på individuelle linjer, hvis det er det vi vil.

fila = open("mini.txt","w",encoding="utf-8")

streng = "Denne setningen vil jeg lagre.\n"

fila.write(streng)

fila.close()

List comprehension 1: Enkle lister

Gitt følgende liste, lag ei liste som ...

liste = [1, 4, 6, 8, 9, 14, 17]

a) ...er hvert tall ganget med 3.

b) ...er hvert tall delt på 1

c) ...er hvert tall + 10

d) ...er hvert tall opphøyd i 3.

Vis løsningsforslag

Løsningsforslag:

liste = [1, 4, 6, 8, 9, 14, 17]
#a
liste_a = [t * 3 for t in liste]

#b
liste_b = [t / 2 for t in liste]

#c
liste_c = [t + 10 for t in liste]

#d
liste_d = [t ** 3 for t in liste]
[3, 12, 18, 24, 27, 42, 51] #a
[0.5, 2.0, 3.0, 4.0, 4.5, 7.0, 8.5] #b
[11, 14, 16, 18, 19, 24, 27] #c
[1, 64, 216, 512, 729, 2744, 4913] #d

List comprehension 2

Bruk list comprehension til å lage følgende lister:

a) Ei liste med kubene (**3) av alle tall for alle tall opp til og med 10.

b) Ei liste med alle heltall fra og med 0 til og med 15.

c) Ei liste av tupler av heltall, der det andre tallet er kvadratet av det første, fra og med 0 til og med 10.

d) Gitt følgende liste:

rotete_data = ["kAke","pålegGsMasKIN","toFU","gARDinSTaNG"]

Lag ei liste med utgangspunkt i rotete_data hvor alle ordene er med store bokstaver.(Tips: .upper())

Vis løsningsforslag

a)

[x ** 3 for x in range(11)]

b)

[x for x in range(0, 16)]

c)

[(x, x ** 2) for x in range(0, 11)]

d)

[x.upper() for x in rotete_data]

List comprehension 3: Lister med tupler

Gitt følgende liste med tupler:

gammel_liste = [('Kari', 'PN'), ('jager', 'VT'), ('dyret', 'N'),
('ved', 'P'), ('vannet', 'N'),('.','SYM')]

a) Lag ei liste med alle ordformene fra setningen.
b) Lag ei liste med alle ordklassetaggene fra setningen.
c) Lag ei liste av tupler hvor det første elementet er ordformen med små bokstaver, og den andre med store.

Vis løsningsforslag

a)

[x[0] for x in gammel_liste]

b)

[x[1] for x in gammel_liste]

c)

[(x[0].lower(),x[0].upper()) for x in gammel_liste]

List comprehension 4: List comprehension med if/else

Gitt denne lista (samme som i list comprehension 3):

gammel_liste = [('Kari', 'PN'), ('jager', 'VT'), ('dyret', 'N'),
('ved', 'P'), ('vannet', 'N'),('.','SYM')]

a) Lag ei liste av alle substantivene.
b) Lag ei liste av alle ordene som ikke er preposisjoner.
c) Lag ei liste av alle ordene som er lengre enn tre tegn.

Gitt følgende liste.

tall = [x for x in range(100)]

a) Lag ei liste av alle partallene.
b) Lag ei liste av alle tallene som har et kvadrat mellom 200 og 500.
c) Lag ei liste der alle partall erstattes av 2 og alle oddetall av 3.

Vis løsningsforslag

Løsningsforslag:

gammel_liste = [('Kari', 'PN'), ('jager', 'VT'), ('dyret', 'N'),
('ved', 'P'), ('vannet', 'N'),('.','SYM')]

print([x[0] for x in gammel_liste if x[1] == "N"])
print([x[0] for x in gammel_liste if x[1] != "P"])
print([x[0] for x in gammel_liste if len(x[0]) > 3])



tall = [x for x in range(100)]

print([x for x in tall if x % 2 == 0])
print([x for x in tall if 200 < x ** 2 < 500])
print([2 if x % 2 == 0 else 3for x in tall])

Utskrifter:

['dyret', 'vannet']
['Kari', 'jager', 'dyret', 'vannet', '.']
['Kari', 'jager', 'dyret', 'vannet']
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
[15, 16, 17, 18, 19, 20, 21, 22]
[2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3]

List comprehension 5: Nøsting

Gitt følgende tekst:

tekst = [['Kari', 'maler', 'huset', '.'], ['Det', 'er', 'lettere',
'overskyet,', 'men', 'varmt', '.'], ['Spurvene', 'leker',
'i', 'dammen', '.']]

a) Lag ei liste med alle ordene.
b) Lag ei liste med alle ordene som ikke er punktum

Følgende oppgaver krever ikke bruk av lista fra a) og b):

c) Lag en 6x6-matrise fylt med 9-ere.
d) Lag en 5x5-matrise hvor hvert element er rad-indeksen ganger kolonne-indeksen (begynn på 0), med mindre produktet er et partall, da skal det være 0.

Vis løsningsforslag

Løsningsforslag:

tekst = [['Kari', 'maler', 'huset', '.'], ['Det', 'er', 'lettere',
'overskyet,', 'men', 'varmt', '.'], ['Spurvene', 'leker',
'i', 'dammen', '.']]

#a
print([w for s in tekst for w in s])
#b
print([w for s in tekst for w in s if w != "."])
#c
print([[9 for i in range(6)] for j in range(6)])
#d
print([[i*j for i in range(5)] for j in range(5)])

Utskrift:

['Kari', 'maler', 'huset', '.', 'Det', 'er', 'lettere', 'overskyet,', 'men', 'varmt', '.', 'Spurvene', 'leker', 'i', 'dammen', '.']
['Kari', 'maler', 'huset', 'Det', 'er', 'lettere', 'overskyet,', 'men', 'varmt', 'Spurvene', 'leker', 'i', 'dammen']
[[9, 9, 9, 9, 9, 9], [9, 9, 9, 9, 9, 9], [9, 9, 9, 9, 9, 9], [9, 9, 9, 9, 9, 9], [9, 9, 9, 9, 9, 9], [9, 9, 9, 9, 9, 9]]
[[0, 0, 0, 0, 0], [0, 1, 2, 3, 4], [0, 2, 4, 6, 8], [0, 3, 6, 9, 12], [0, 4, 8, 12, 16]]

Lister 0: introduksjon

Ei liste er en samling. Det er en type datastruktur som kan "ta vare på" flere andre verdier. Vi kan ha hvilke som helst verdier inne i listene, også andre lister.
Lister med lister kalles nøstede lister, eller flerdimensjonale lister.

Lister brukes ofte sammen med løkker. For å gjøre det enklere inneholder ikke de første oppgavene her løkker. Du kan bruke taggen "løkker" for å øve på dem.

Eksempler:

tom_liste = []
strengliste = ["pute","dyne","pledd"]
heltalliste = [1,2,3,4]
flyttalliste = [1.4,5.2,4.7]
listeliste = [[1,2,3],[4,5,6],[7,8,9]]

For å legge til flere elementer i ei liste, bruker vi metoden .append().

Eksempel

strengliste.append("laken")

Vi henter ut elementene av ei liste ved å bruke indekser. Det første elementet i ei liste har indeks 0.

Eksempel:

#Skrive ut det første elementet
print(strengliste[0])
#skrive ut det andre elementet
print(strengliste[1])

Utskrift:

pute
dyne

Innføringsoppgave

Lag en kort liste med hver av typene: streng, heltall, flyttall, boolsk verdi, liste.
Skriv dem ut i terminalen.

Vis løsningsforslag

Øvelsesoppgave

Dette er bare et eksempel. Oppgaven er bare for at du skal øve på å lage lister med ulike datatyper.

str_liste = ["a","be","se","det"]
int_liste = [2,4,6,8,16]
float_liste = [1.5,3.0,4.5,6.0]
bool_liste = [True,False,True,True,False]
list_liste = [["alfa","beta"],["gamma","delta"]]
print(str_liste)
print(int_liste)
print(float_liste)
print(bool_liste)
print(list_liste)

Lister 1: å legge til i lister

Oppgaver

a) Legg til de tre strengene nedenfor i lista nedenfor.

streng1 = "or"
streng2 = "gran"
streng3 = "furu"

ny_liste = ["bjørk","bøk","osp"]

b) Tidligere har vi vært borti metoden .split() som gjør om en streng til ei liste. Bruk metoden på strengen under, og skriv så ut det andre og det fjerde elementet i lista til terminalen.

tekst = "Jeg er så glad hver julekveld ."

c) Lag et program som tar inn tre ord fra brukeren og legger dem i ei liste. Begynn med å lage ei tom liste, og legg orda til. Når brukeren er ferdig skal du skrive ut lista til terminalen.

d) Lag ei ny liste av lista under, vet at du henter ut det første, tredje og femte elementet og setter dem i ei ny liste. Skriv lista ut til terminalen.

gammel_liste = ["laks","ørret","flyndre","fjesing","sild","knurr"]
Vis løsningsforslag

a)

streng1 = "or"
streng2 = "gran"
streng3 = "furu"

ny_liste = ["bjørk","bøk","osp"]

ny_liste.append(streng1)
ny_liste.append(streng2)
ny_liste.append(streng3)
print(ny_liste)

b)

tekst = "Jeg er så glad hver julekveld ."

ny_liste = tekst.split()

andre_ord = ny_liste[1]
fjerde_ord = ny_liste[3]

print(andre_ord)
print(fjerde_ord)

c)

ord1 = input("Skriv et ord!\n")
ord2 = input("Skriv enda et ord!\n")
ord3 = input("Skriv enda et ord!\n")

ny_liste = []
ny_liste.append(ord1)
ny_liste.append(ord2)
ny_liste.append(ord3)
print(ny_liste)

Utskrift:

>>>Skriv et ord!
løkskall
>>>Skriv enda et ord!
rødkål
>>>Skriv enda et ord!
kastanjer
['løkskall', 'rødkål', 'kastanjer']

Vi kunne lagt til ordene etter hver gang brukeren skriver noe. Siden vi vet hvor mange ord som kommer, så kunne vi også lagt dem rett inn i ei liste, slik:

ny_liste = [ord1, ord2, ord3]

d)

Denne kan også løses på (minst) to måter:

gammel_liste = ["laks","ørret","flyndre","fjesing","sild","knurr"]
ny_liste = []
ny_liste.append(gammel_liste[0])
ny_liste.append(gammel_liste[2])
ny_liste.append(gammel_liste[4])
print(ny_liste)

Eller, siden vi vet hvor mange elementer vi skal ha med:

gammel_liste = ["laks","ørret","flyndre","fjesing","sild","knurr"]
ny_liste = [gammel_liste[0], gammel_liste[2], gammel_liste[4]]

print(ny_liste)

Utskrift i begge tilfellene:

['laks', 'flyndre', 'sild']

Lister 2 : å telle elementer

For å telle elementer i lister er det to subrutiner som er fine å kunne. Den første er metoden .count(), og den andre er funksjonen len(). Count fungerer på lister veldig likt som på strenger, men den går gjennom elementene i lista og sjekker dem.

Eksempel:

liste = [1,2,1,4,5,5,1,2,2,2]
print(liste.count(2))

Utskrift:

4

Merk at den ikke sjekker innad i elementene i lista. Se på antall tilfeller av "ei" i lista nedenfor:

liste2 = ["eie", "meie", "ei", "einebær", "soleie"]
print(liste2.count("ei"))

Utskrift:

1

len() sjekker bare hvor mange elementer det er totalt i ei liste. Merk også hvordan syntaksen til len() er annerledes fra .count().

liste3 = [1,2,3,4,5,6,7,8,9]
liste4 = ["ristet brød med avokado", "sviskegrøt med fløte"]

print(len(liste3))
print(len(liste4))
9
2

Oppgaver

a) Bruk len() til å finne ut lengden til listene under, men tenk over hvor lange de er ved å se på dem først. Skriv ut svaret til terminalen.

liste1 = ["o","s","t","e","p","o","p"]
liste2 = [9.5,2.2,4.5,3.1,23.5]
liste3 = [[1,2,3,4,5,8],[11,13,15,18]]

b) Bruk .split() og len() til å finne ut hvor mange ord det er i verset under fra Trymskvida. Her kan det lønne seg å skrive ut lista du får, for å sjekke om du deler opp strengen riktig.

tekst = """Vreid var Vingtor
då han vakna
og hamaren sin
han munde sakne .
Skjegg han riste,
hedna han skok ;
tok son åt Jord
um seg å trivle ."""

c) Bruk .split() og .count() på teksten under til å telle følgende. Teksten er to vers fra Grottesang fra den Yngre Edda. Skriv ut til terminalen.

c1) Hvor mange ganger forekommer ordet "ei" i teksten?
c2) Hvor mange ganger forekommer kommaet?
c3) Hvor mange ganger forekommer ordet "til"?
c4) Hvor mange prosent av alle ordene er tegnsetting? (ikke regn med ’ i "bro’rs"). Her kan du bruke len() i tillegg.

tekst2 = """Her skal ingen andre skade , vaade ei volde , vorde til bane ,
hugge end ei da med hvasse sverd , om bro’rs bane han bunden ser .

Grotte ei kommen af graafjeld var , ei den haarde hald af mulde ,
ei bjergtrolds mø nu malte saa , hørte trolddom ei hende til ."""

d) Skriv et program som tar inn input fra brukeren, der brukeren først kan skrive en (lengre) tekst. Så kan brukeren spesifisere et ord som skal telles. Skriv ut til terminalen hvor mange ganger ordet som brukeren spesifiserer forekommer i teksten de skrev.

Vis løsningsforslag

a)

liste1 = ["o","s","t","e","p","o","p"]
liste2 = [9.5,2.2,4.5,3.1,23.5]
liste3 = [[1,2,3,4,5,8],[11,13,15,18]]

print(len(liste1))
print(len(liste2))
print(len(liste3))

Utskrift:

7
5
2

Den siste er to fordi det bare er to lister i lista (nøstet liste). Det er likegyldig hvor mange elementer det er i de to listene.

b)

tekst = """Vreid var Vingtor
då han vakna
og hamaren sin
han munde sakne .
Skjegg han riste,
hedna han skok ;
tok son åt Jord
um seg å trivle ."""

lista = tekst.split()
print(lista) #for å sjekke
print(len(lista))

Utskrift:

['Vreid', 'var', 'Vingtor', 'då', 'han', 'vakna', 'og', 'hamaren', 'sin', 'han', 'munde', 'sakne', '.', 'Skjegg', 'han', 'riste,', 'hedna', 'han', 'skok', ';', 'tok', 'son', 'åt', 'Jord', 'um', 'seg', 'å', 'trivle', '.']
29

Her lønner det seg å bruke .split() uten argument (spesifisert streng), siden vi vil dele den på både linjeskift og mellomrom.

c)

tekst2 = """Her skal ingen andre skade , vaade ei volde , vorde til bane ,
hugge end ei da med hvasse sverd , om bro’rs bane han bunden ser .

Grotte ei kommen af graafjeld var , ei den haarde hald af mulde ,
ei bjergtrolds mø nu malte saa , hørte trolddom ei hende til ."""

#gjøre om til liste
splitta = tekst2.split()

#svar på de tre første spørsmålene
print("'ei' forekommer", splitta.count("ei"), "ganger")
print("Kommaet forekommer",splitta.count(","),"ganger")
print("Ordet 'til' forekommer",splitta.count("til"),"ganger")

#for å regne ut c4):
antall_komma = splitta.count(",") #samme som i oppgave c2.
antall_punktum = splitta.count(".")

#så legger vi sammen de to:
tegnsetting = antall_komma + antall_punktum

#så finner vi hvor mange ord det er totalt:
totalt = len(splitta)
print(totalt)

#så regner vi ut prosenten
prosent_tegnsetting = tegnsetting / totalt * 100

print("Tegnsetting utgjør",prosent_tegnsetting,"prosent.")

d)

teksten = input("Skriv en tekst.\n")
ordet = input("Skriv et ord du vil telle.\n")
antall = teksten.count(ordet)
print("Ordet",ordet,"forekommer",antall,"ganger i teksten din.")

Utskrift:

>>>Skriv en tekst.
I dag har jeg spist potetgull og jeg har sovet og jeg har lest pensum .
>>>Skriv et ord du vil telle.
jeg
Ordet jeg forekommer 3 ganger i teksten din.

Lister 3: å fjerne elementer

Her skal vi se på to måter å fjerne et element fra ei liste: .remove() og .pop()

Remove brukes ved at man spesifiserer selve elementet man vil fjerne. Remove fjerner så den første forekomsten av elementet. Hvis elementet ikke finnes i lista og man prøver å fjerne det får man en feilmelding. Vi kan bruke den boolske operatoren in for å sjekke om elementet finnes.

Eksempel

liste =    ["en","to","tre","fire"]
print(liste)
liste.remove("fem")

Utskrift med feilmelding:

['en', 'to', 'tre', 'fire']
Traceback (most recent call last):
  File "listetest.py", line 5, in <module>
    liste.remove("fem")
ValueError: list.remove(x): x not in list

(listetest.py er navnet på fila.)
Men hvis vi sjekker med in:

liste =    ["en","to","tre","fire"]
print(liste)
if "fem" in liste:
    liste.remove("fem")
else:
    liste.remove("fire")
print(liste)

Da får vi følgende utskrift:

['en', 'to', 'tre', 'fire']
['en', 'to', 'tre']

Når vi bruker .pop() kan vi velge å spesifisere en indeks, eller la være å spesifisere. Hvis vi ikke spesifiserer noe så fjerner den alltid det siste elementet i lista.

liste =    ["en","to","tre","fire","fem"]
liste.pop()
print(liste)
liste.pop(1)
print(liste)

Utskrift:

["en", "to", "tre", "fire"]
["en", "tre", "fire"]

Legg merke til at liste.pop(1) fjerner elementet "to".

Oppgaver

a) Fjern elementene "balkong" og "drivhus" fra lista under ved å bruke .remove(), og skriv ut den resulterende lista til terminalen.

liste1 = ["balkong","veranda","altan","terasse","drivhus"]

b) Fjern elementene "balkong" og "drivhus" fra lista under ved å bruke .pop(), og skriv ut den resulterende lista til terminalen. Tips: tenk på hva som skjer når du har fjernet det ene elementet.

liste1 = ["balkong","veranda","altan","terasse","drivhus"]

c) Lag et program der brukeren skriver inn en setning. Ta setningen og del den opp ved å bruke .split(). Brukeren skal så skrive inn et ord som skal fjernes. Hvis ordet finnes i lista så skal det fjernes og lista skrives ut til terminalen, hvis ikke skal brukeren få ei melding om at ordet ikke finnes i lista.

Vis løsningsforslag

a)
Med .remove() trenger vi altså bare å skrive elementene vi vil fjerne.

liste1 = ["balkong","veranda","altan","terasse","drivhus"]

liste1.remove("balkong")
liste1.remove("drivhus")
print(liste1)

Utskrift:

['veranda', 'altan', 'terasse']

b)
Indeksene vi velger avhenger av hvilken rekkefølge elementene fjernes i. Dette gjelder kun .pop(), ikke remove. Hvis vi fjerner "balkong" først, vil det kun være fire elementer i lista, og den siste indeksen er derfor 3. Hvis vi fjerner "drivhus" først så er det fortsatt fem elementer i lista, så indeksen til "drivhus" er 4.

liste1 = ["balkong","veranda","altan","terasse","drivhus"]

liste1.pop(0)
liste1.pop(3)

print(liste1)

Eller:

liste1 = ["balkong","veranda","altan","terasse","drivhus"]

liste1.pop(4)
liste1.pop(0)

print(liste1)

Utskriften blir lik i begge tilfeller:

['veranda', 'altan', 'terasse']

c)
Det er mange måter å løse oppgaven på. Dette er et forslag.

setning = input("Skriv en setning med noen ord.\n")
setning_splitta = setning.split()
ord_fjerne = input("Hvilket ord vil du fjerne? Skriv ett ord.\n")
if ord_fjerne in setning_splitta:
    setning_splitta.remove(ord_fjerne)
    print("Setning uten",ord_fjerne,":",setning_splitta)
else:
    print("Ordet",ord_fjerne,"finnes ikke i lista. Ingen endring gjort.")

Utskrift med ord som finnes i lista:

>>Skriv en setning med noen ord.
Det sitter en fugl i treet .
>>Hvilket ord vil du fjerne? Skriv ett ord.
fugl
>>>Setning uten fugl : ['Det', 'sitter', 'en', 'i', 'treet', '.']

Utskrift med ord som ikke finnes i lista:

>>>Skriv en setning med noen ord.
Det sitter en fugl i treet .
>>>Hvilket ord vil du fjerne? Skriv ett ord.
ost
>>>Ordet ost finnes ikke i lista. Ingen endring gjort.

Lister 4: sortering

Ofte når vi jobber med tekst har vi behov for å sortere lister på en eller annen måte. Her skal vi bare ta for oss enkel bruk av .sort()-metoden. Vi kan velge å sortere baklengs ved å spesifisere .sort(reverse=True). Her bruker vi nøkkelordargumentet(key word argument) "reverse", og gir det den boolske verdien True. Metoden sorterer tall i rekkefølge, og strenger i alfabetisk rekkefølge.

Eksempel:

strengliste1 = ["d","a","m","b","c","g"]
talliste1 = [6,3,9,3,8,1,2]
strengliste2 = ["d","a","m","b","c","g"]
talliste2 = [6,3,9,3,8,1,2]

strengliste1.sort()
talliste1.sort()
strengliste2.sort(reverse=True)
talliste2.sort(reverse=True)

print(strengliste1)
print(talliste1)
print(strengliste2)
print(talliste2)
['a', 'b', 'c', 'd', 'g', 'm']
[1, 2, 3, 3, 6, 8, 9]
['m', 'g', 'd', 'c', 'b', 'a']
[9, 8, 6, 3, 3, 2, 1]

Oppgaver

a) Sorter lista under og skriv den ut til terminalen.
b) Sorter lista under i motsatt rekkefølge og skriv den ut til terminalen.

liste1 = ["åme","larve","kryp","mark","snegle","bille"]

c) Del opp teksten under (NRK) og skriv ut det ordet som er først i alfabetisk rekkefølge, og det ordet som er sist i alfabetisk rekkefølge. Tips: vi kan skrive liste[-1] for å få tak i det siste elementet i ei liste.

tekst = """Derfor måtte dei utvikle ein ny metode . Denne er basert på bruken av ein heilt ny type høgenergi røntgenteknologi , saman med ein type kunstig intelligens kalla maskinlæring . Maskinlæring er ifølgje Wikipedia ein vitskapleg disiplin som utviklar algoritmar , som igjen gjer datamaskinar i stand til å lære frå og utvikle framferd basert på empiriske data ."""

d) Lag et program der brukeren skal skrive inn ei liste med ord, adskilt med mellomrom (F.eks. "ost melk kake"). Ta så inn input fra brukeren som skal bestemme om lista skal sorteres i vanlig eller motsatt rekkefølge. Sorter lista etter brukerens ønske, og skriv den ut til terminalen.

Vis løsningsforslag

a)

liste1 = ["åme","larve","kryp","mark","snegle","bille"]

liste1.sort()

print(liste1)

Utskrift:

['bille', 'kryp', 'larve', 'mark', 'snegle', 'åme']

b)

liste1 = ["åme","larve","kryp","mark","snegle","bille"]

liste1.sort(reverse=True)

print(liste1)

Utskrift:

['åme', 'snegle', 'mark', 'larve', 'kryp', 'bille']

c)

tekst = """Derfor måtte dei utvikle ein ny metode . Denne er basert på bruken av ein heilt ny type høgenergi røntgenteknologi , saman med ein type\
 kunstig intelligens kalla maskinlæring . Maskinlæring er ifølgje Wikipedia ein vitskapleg disiplin som utviklar algoritmar , som igjen gjer datam\
askinar i stand til å lære frå og utvikle framferd basert på empiriske data ."""

tekst_liste = tekst.split()
#sorterer så det kommer i alfabetisk rekkefølge                                                                                                    
tekst_liste.sort()
print("Det første ordet:",tekst_liste[0])
print("Det siste ordet:",tekst_liste[-1])

Siden .sort() gjør at alt kommer i alfabetisk rekkefølge kan vi ta det første og det siste elementet. Vi kunne selvsagt også gjort det motsatt, og sortert med .sort(reverse=True), men da ville det første elementet vært tekst_liste[-1], og det siste vært tekst_liste[0].

I tillegg til å kunne bruke negative indekser for å hente ut elementer fra slutten av ei liste, som tekst_liste[-1], kunne vi også skrevet tekst_liste[len(tekst_liste) - 1]. Å bruke negative indekser er litt spesielt for Python, og det er ikke alle språk som har den funksjonaliteten. Vi må ha - 1 fordi tallet som indikerer lengden på ei liste alltid vil være én mer enn den høyeste indeksen, siden indeksen i ei liste begynner på 0.

Utskrift:

Det første ordet: ,
Det siste ordet: å

Vi ser at tegnsetting sorteres før bokstavene, og at den norske å-en kommer sent, som den skal.

d)

Vi tar inn det vi trenger fra brukeren, og splitter strengene før vi sjekker om brukeren svarte ja eller nei.

brukerliste =    input("Skriv flere ord etter hverandre med mellomrom.\n")
vanlig_rekkefoelge = input("Vil du sortere i vanlig rekkefølge? Svar 'ja' eller 'nei'.\n")

liste =    brukerliste.split()

if vanlig_rekkefoelge.lower() == "ja":
    liste.sort()
    print("Du har valgt å sortere i vanlig rekkefølge:")
    print(liste)
else:
    liste.sort(reverse=True)
    print("Du har valgt å sortere i motsatt rekkefølge:")
    print(liste)

Grunnen til å ha .lower() på variabelen er bare for å forhindre at "Ja" (med stor J) gir feil resultat. Det er en av flere ting vi kan gjøre for å gi en bedre brukeropplevelse.

Utskrift med "ja":

>>>Skriv flere ord etter hverandre med mellomrom.
pære fiken vannmelon eple rambutan
>>>Vil du sortere i vanlig rekkefølge? Svar 'ja' eller 'nei'.
ja
>>>Du har valgt å sortere i vanlig rekkefølge:
>>>['eple', 'fiken', 'pære', 'rambutan', 'vannmelon']

Utskrift med "nei":

>>>Skriv flere ord etter hverandre med mellomrom.
pære fiken vannmelon eple rambutan
>>>Vil du sortere i vanlig rekkefølge? Svar 'ja' eller 'nei'.
nei
>>>Du har valgt å sortere i motsatt rekkefølge:
>>>['vannmelon', 'rambutan', 'pære', 'fiken', 'eple']

Løkker 0: introduksjon

Løkker er det vi bruekr for å gå igjennom en samling, og gjøre samme operasjon på ett eller flere elementer etter hverandre. I Python er de viktigste nøkkelordene når det gjelder løkker for og while. For-løkker bruker nøkkelordet for og brukes hovedsaklig sammen med en samling, som for eksempel en streng, ei liste eller ei ordbok. while-løkker brukes sammen med et boolsk uttrykk, og gjør samme ting helt til det boolske uttrykket blir usant.

Å gå igjennom en samling kaller vi å iterere, og en gjennomgang er en iterasjon.

En for-løkke brukes alltid på noe som er itererbart, det vil si at det er mulig å gå igjennom samlingen ett etter ett element om gangen. Lister, ordbøker, strenger, tupler og mengder er alle itererbare.

Her er et eksempel der vi itererer gjennom ei liste med heltall, og skriver ut hvert tall ganget med 2. Vi ganger med to én gang per iterasjon, altså per gjennomgang. Når vi skriver for x in... er for ordet som viser at vi skal ha en for-løkke, x er navnet som gis til hvert element for hver iterasjon, og in bruker vi foran samlingen vi skal gå igjennom. Husk at x bør ha et navn som sier noe om hva slags verdi vi har med å gjøre, og at verdien til x endrer seg hver gang. Vi kan lese en for-løkke omtrent som "For hvert element in denne samlingen, la hvert element hete x, og gjør følgende:". Merk at in i dette tilfellet brukes annerledes enn det vi er vant med fra in som boolsk operator.

liste = [1,2,3,4,5]
for tall in liste:
    print(tall * 2)

Utskrift:

Tupler og mengder oppfører seg i dette tilfellet helt likt som lister, men ordbøker er litt annerledes. Hvis vi itererer gjennom ei ordbok uten å spesifisere noe mer enn vi gjorde i eksempelet over med lista, så skriver vi ut nøklene i ordboka:

ordbok = {'a':1,'b':2,'c':3}

for symbol in ordbok:
    print(symbol * 2)

Utskrift:

aa
bb
cc

Hvis vi skal ha med både nøkkelverdier og innholdsverdier i ei ordbok, må vi enten slå opp på nøkkelen, eller bruke metoden .items(), slik:

ordbok = {'a':1,'b':2,'c':3}
for symbol in ordbok:
    print(symbol,ordbok[symbol])

for symbol, tall in ordbok.items():
    print(symbol, tall)

De gir samme utskrift:

a 1
b 2
c 3
a 1
b 2
c 3

En while-løkke har nøkkelordet while, etterfulgt av et boolsk uttrykk, altså et uttrykk som evalueres til True eller False. Det er viktig at det er mulig for uttrykket å bli false, slik at løkken ikke varer evig. En while-løkke som ikke slutter er en vanlig grunn til at programmet "setter seg fast" og kjører, uten at det skjer noe.

Et enkelt eksempel kan være at vi spør brukeren om å skrive ord, og at vi legger disse til i ei liste, helt til brukeren skriver "ferdig". Ordet "ferdig" er da det som gjør at løkken avsluttes. Når programmet er ferdig skriver vi ut lista. Vi kan lese syntaksen som "Så lenge det er sant at...gjør følgende:"

liste = []
svar = input("Skriv et ord, eller skriv 'ferdig' for å avslutte.\n").lower()
while svar != "ferdig":
    liste.append(svar)
    svar = input("Skriv et ord, eller skriv 'ferdig' for å avslutte.\n").lower()
print(liste)

Merk at utskriften til terminalen kun vil skje når løkka er ferdig.

Eksempel på kjøring:

>>>Skriv et ord, eller skriv 'ferdig' for å avslutte.
svovel
>>>Skriv et ord, eller skriv 'ferdig' for å avslutte.
saltpeter
>>>Skriv et ord, eller skriv 'ferdig' for å avslutte.
kull
>>>Skriv et ord, eller skriv 'ferdig' for å avslutte.
ferdig
['svovel', 'saltpeter', 'kull']

Legg merke til at "ferdig" ikke kommer med i lista, siden vi legger inn ordene først etter at vi har sjekket om de er like "ferdig" eller ikke. Vi bruker .lower() for å passe på at vi avslutter selv om brukeren skriver "Ferdig" eller andre sammensetninger av store og små bokstaver.

range

En vanlig ting å bruke løkker til er for å gjenta noe et visst antall ganger. Det er minst to måter å gjøre dette på: å bruke en variabel som teller opp eller ned, sammen med en while-løkke som avsluttes når variabelen når en bestemt verdi; eller en for-løkke sammen med range. Range gir oss en (slags) liste med heltall som vi kan bruke. Vi bruker ofte variabelnavnet "i" når vi bruker range. Dette henger sammen med lignende matematisk notasjon.

Funksjonen range() tar opptil tre parametre:

Hvis vi bare spesifiserer ett argument, betyr det at vi får alle heltallene fra og med 0, til men ikke inkludert det tallet vi spesifiserer.

for i in range(8):
    print(i)

Dette gir oss:

0
1
2
3
4
5
6
7

Hvis vi spesifiserer to argumenter, så tolkes rekkevidden som fra og med det første tallet, til men ikke inkludert det andre, akkurat som med slicing.

for i in range(2,8):
    print(i)

Dette gir oss altså fra og med 2, til men ikke inkludert 8.

2
3
4
5
6
7

Hvis vi spesifiserer tre tall, så vil det tredje tallet tolkes som avstanden mellom hvert tall. Vanligvis er dette 1, men vi kan velge hva vi vil. Koden under ber altså om hvert andre tall fra og med 2, til men ikke inkludert 8:

for i in range(2,8,2):
    print(i)

Og vi får:

2
4
6

Løkker 1: for-løkker

I de følgende oppgavene skal du bruke for-løkker.

a) Skriv ut hvert element i samlingene under. Prøv å gi variabelen i for-løkka et meningsfylt navn.

liste1 = [1,2,3,4,5]
streng = "kirsebærpai"
liste2 = [[1,2,3],[4,5,6]]

b) Sett sammen alle strengene i lista under til én streng, og skriv den ut til terminalen. Begynn med å opprette en tom streng.

liste3 = ['j', 'e', 'g', ' ', 'e', 'l', 's', 'k', 'e', 'r', ' ', 'l', 'ø', 'k', 'k', 'e', 'r']

c) Hva er summen av lengden til alle orda i lista under? Bruk ei for-løkke for å regne det ut, og skriv ut svaret til terminalen. Begynn med å opprette en heltallsvariabel til å holde på summen.

liste4 = ['regn', 'yr', 'tåke', 'dis', 'storm', 'torden', 'lyn']

d) Iterer gjennom lista med heltall under, gang hvert tall med seg selv, og skriv ut resultatet til terminalen.

liste5 = [2, 4, 8, 16, 32, 64]
Vis løsningsforslag

Løsningsforslag

liste1 = [1,2,3,4,5]
streng = "kirsebærpai"
liste2 = [[1,2,3],[4,5,6]]

for tall in liste1:
    print(tall)

for bokstav in streng:
    print(bokstav)

for liste in liste2:
    print(liste)

Det er selvsagt mange andre ting vi kunne kalt variablene, men det viktigste er at man skjønner mer eller mindre hva det dreier seg om, så koden blir enklere å lese.

1
2
3
4
5

k
i
r
s
e
b
æ
r
p
a
i

[1, 2, 3]
[4, 5, 6]

b)

liste3 = ['j', 'e', 'g', ' ', 'e', 'l', 's', 'k', 'e', 'r', ' ', 'l', 'ø', 'k', 'k', 'e', 'r']

nystreng = ""

for bokstav in liste3:
    nystreng = nystreng + bokstav

print("Den nye strengen er:", nystreng)

Eller, med litt mer kompakt notasjon:

liste3 = ['j', 'e', 'g', ' ', 'e', 'l', 's', 'k', 'e', 'r', ' ', 'l', 'ø', 'k', 'k', 'e', 'r']

for bokstav in liste3:
    nystreng += bokstav

print("Den nye strengen er:", nystreng)

Utskrift i begge tilfeller:

Den nye strengen er: jeg elsker løkker

c)

liste4 = ['regn', 'yr', 'tåke', 'dis', 'storm', 'torden', 'lyn']

summen = 0
for ordet in liste4:
    summen = summen + len(ordet)

print("Summen er:",summen)

Eller, med mer kompakt notasjon, som over:

liste4 = ['regn', 'yr', 'tåke', 'dis', 'storm', 'torden', 'lyn']

summen = 0

for ordet in liste4:
    summen += len(ordet)

print("Summen er:",summen)

Merk at vi ikke bør bruke ord eller sum som variabelnavn. Dette er reserverte ord i Python, og selv om man ikke får problemer i små programmer, så er det noe vi bør unngå.

Utskrift i begge tilfeller:

Summen er: 27

d)

liste5 = [2, 4, 8, 16, 32, 64]

for tall in liste5:
    produkt = tall * tall
    print(produkt)

Vi kan la være å mellomlagre verdien i en variabel, siden vi ikke skal bruke den igjen seinere i dette tilfellet:

liste5 = [2, 4, 8, 16, 32, 64]
for tall in liste5:
    print(tall*tall)

Utskriften i begge tilfeller er lik:

4
16
64
256
1024
4096

Løkker 2: for-løkker med range

I disse oppgavene skal du bruke for-løkker sammen med range.

a) Skriv ut en beskjed (som "Hei!") til brukeren fem ganger.

b) Ta inn fem ord fra brukeren og legg dem i ei liste. Skriv ut lista når løkka er ferdig.

c) Ta inn fem nye ord fra brukeren. Gang hvert ord med tallvariabelen til range(), og legg så hvert ord inn i ei liste. Skriv ut lista når løkka er ferdig.

d) Bruk range til å gå gjennom lista med ord under. Du må altså tenke over hvordan du kan bruke tallene fra range() til å få tak i elementene i lista.

liste1 = ['glass', 'betong', 'sand', 'murstein', 'sement']

e) Bruk range() til å regne ut summen av alle heltall fra og med 0 til og med 100.

f) Bruk range() til å regne ut summen av alle partall fra og med 0 til og med 100.

g) Bruk range() til å regne ut summen av alle oddetall fra og med 1 til og med 101.

h) En liten utfordring! Bruk range() sammen med lista under til å gjøre følgende: For hver streng i lista under skal du sette ordet sammen med ordet etter, og legge det i ei ny liste. Den siste strengen skal kun med som siste elementet i sammensetningen med ordet foran, den skal ikke med alene.

liste2 = ['kanel', 'kardemomme', 'nellik', 'safran', 'pepper', 'vanilje', 'muskat']
Vis løsningsforslag

Løsningsforslag

a)

for i in range(5):
    print("Hei!")

Utskrift

Hei!
Hei!
Hei!
Hei!
Hei!

b)

ny_liste = []
for i in range(5):
    svar = input("Skriv et ord.\n")
    ny_liste.append(svar)

print(ny_liste)

Utskrift:

>>>Skriv et ord.
sur
>>>Skriv et ord.
søt
>>>Skriv et ord.
bitter
>>>Skriv et ord.
salt
>>>Skriv et ord.
sterk
['sur', 'søt', 'bitter', 'salt', 'sterk']

c)

ny_liste2 = []
for i in range(5):
    svar = input("Skriv et ord.\n")
    ny_liste2.append(svar*i)

print(ny_liste2)

Utskrift:

>>>Skriv et ord.
hvem
>>>Skriv et ord.
hva
>>>Skriv et ord.
hvor
>>>Skriv et ord.
hvordan
>>>Skriv et ord.
hvorfor
['', 'hva', 'hvorhvor', 'hvordanhvordanhvordan', 'hvorforhvorforhvorforhvorfor']

Tenk over hvorfor det første elementet er en tom streng.

d)

liste1 = ['glass', 'betong', 'sand', 'murstein', 'sement']

for i in range(len(liste1)):
    print(liste1[i])

Utskrift:

Oppgave e, f og g henger sammen med utregning av summer. I mer formell notasjon ser vi dette som sigma-notasjon, som dere kommer til å komme borti seinere i faget.

e)

sum_heltall = 0
for i in range(101):
    sum_heltall += i
print(sum_heltall)

Utskrift:

5050

f)

sum_partall = 0
for i in range(0,101,2):
    sum_partall += i
print(sum_partall)

Utskrift:

2550

g)

sum_oddetall = 0
for i in range(1,102,2):
    sum_oddetall += i
print(sum_oddetall)

Utskrift:

2601

h)
Et av poengene med denne oppgaven er at man må huske å ha med -1 i indeksen så man ikke prøver å få tak i elementet etter det siste elementet, siden man da går utenfor lista.

liste2 = ['kanel', 'kardemomme', 'nellik', 'safran', 'pepper', 'vanilje', 'muskat']

sammensatte_ord = []
for i in range(len(liste2) - 1):
    sammensatt = liste2[i] + liste2[i + 1]
    sammensatte_ord.append(sammensatt)
print(sammensatte_ord)

Utskrift:

['kanelkardemomme', 'kardemommenellik', 'nelliksafran', 'safranpepper', 'peppervanilje', 'vaniljemuskat']

Det finnes en funksjon som gjør det vi gjør i e) og h) litt enklere, altså å ha tilgang til indeksene og elementene i ei liste samtidig. Den heter enumerate(), men vi behandler den ikke her.

Løkker 3: while-løkker

I denne oppgaven skal du bruke while-løkker

a) Skriv et program som ber brukeren legge til ett og ett ord helt til brukeren skriver "ferdig". Når brukeren er ferdig skal den få muligheten til å gjette på hvor mange ord som ble lagt inn. Skriv ut om svaret var riktig eller ikke, og hva det riktige svaret var.

b) Bruk en while-løkke sammen med en indeks-variabel som starter på 0, og gå gjennom lista under. Elementene i lista skal skrives ut, sammen med hvor lange de er, helt til du kommer til et ord som er lengre enn 9 tegn, da skal løkka avsluttes, og ordet med fler enn 9 tegn skal skrives ut.

liste = ['mel', 'pepper', 'salt', 'ris', 'saus', 'sitron', 'aubergine', 'kjele', 'kardemomme', 'ost']

c) Spørrelek. Lag ei ordbok med minst tre spørsmål, der spørsmålet er nøkkelverdien, og svaret er innholdsverdien. Iterer gjennom ordboka, og for hver iterasjon skal du kjøre ei while-løkke som ber brukeren svare. Hvis brukeren gir opp ved å svare "neste" (eller noe annet, du bestemmer!), eller svarer riktig, så skal du gå videre til neste spørsmål. Lagre antall riktige i en egen variabel, og skriv ut denne med en hyggelig melding til brukeren når de har svart på alle spørsmålene.

Vis løsningsforslag

Disse oppgavene begynner å bli mer kompliserte, og det gjør at det er mange måter å løse dem på. Det gjelder spesielt måter man kan håndtere input fra brukeren på, i tilfelle brukeren skrive noe feil, og om man skal spørre igjen, osv. Løsningene under er kun forslag.

a)

liste_med_ord = []
svar = input("Skriv et ord.\n").lower()
while svar != "ferdig":
    liste_med_ord.append(svar)
    svar = input("Skriv et ord.\n").lower()
hvor_mange = input("Hvor mange ord la du inn?\n")
hvor_mange = int(hvor_mange)
if hvor_mange == len(liste_med_ord):
    print("Du gjettet riktig! Det var", len(liste_med_ord), "ord.")
else:
    print("Det var dessverre feil. Det var ",len(liste_med_ord), "ord i lista.")

Utskrift:

>>>Skriv et ord.
murstein
>>>Skriv et ord.
flis
>>>Skriv et ord.
takstein
>>>Skriv et ord.
kalk
>>>Skriv et ord.
ferdig
>>>Hvor mange ord la du inn?
4
>>>Du gjettet riktig! Det var 4 ord.

b)

liste = ['mel', 'pepper', 'salt', 'ris', 'saus', 'sitron', 'aubergine', 'kjele', 'kardemomme', 'ost']
indeks = 0
element = liste[indeks]
while len(element) < 10:
    print(element,"har",len(element),"bokstaver.")
    indeks += 1
    element = liste[indeks]
print(element,"har flere enn 9 bokstaver!")

Utskrift:

mel har 3 bokstaver.
pepper har 6 bokstaver.
salt har 4 bokstaver.
ris har 3 bokstaver.
saus har 4 bokstaver.
sitron har 6 bokstaver.
aubergine har 9 bokstaver.
kjele har 5 bokstaver.
kardemomme har flere enn 9 bokstaver!

c)

ordbok = {"Hva er hovedstaden i Norge?":"Oslo","Hva lages rismelk av?":"Ris","Hva sier kua?":"Mø"}
riktig = 0
for spoersmaal in ordbok:
    print(spoersmaal)
    svar = input()
    while svar != ordbok[spoersmaal] and svar != "gir opp":
        print(spoersmaal)
        svar = input("Prøv igjen eller skriv 'gir opp' for å gi opp.\n")
    if svar == "gir opp":
        print("Bedre lykke på neste spørsmål!")
    else:
        print("Veldig bra:D")
        riktig += 1
print("Leken er ferdig. Du fikk",riktig," av 3 poeng riktig!")

Utskrift:

>>>Hva er hovedstaden i Norge?
Oslo
>>>Veldig bra:D
>>>Hva lages rismelk av?
melk
>>>Hva lages rismelk av?
>>>Prøv igjen eller skriv 'gir opp' for å gi opp.
gir opp
>>>Bedre lykke på neste spørsmål!
>>>Hva sier kua?
Mø
>>>Veldig bra:D
>>>Leken er ferdig. Du fikk 2  av 3 poeng riktig!

N-gram (Utfordringsoppgave)

Vanligvis bruker vi nltk sin n-gram-metode (eller tilsvarende), for å slippe å implementere noe selv. Ferdigimplementerte metoder er også ofte mer effektivt implementert enn det vi får til selv. For øvelsens skyld, og fordi det kan være gøy, skal du prøve å implementere n-grammer selv i denne oppgaven.

Et n-gram er en liste med tupler som deler opp en liste (ofte en setning), slik at alle kombinasjoner kommer med. Det lar oss modelere sammenhenger i ord på en grei måte. "n" i n-gram står for et vilkårlig tall. 1-gram kalles også unigram, 2-gram kalles bigram og 3-gram kalles trigram, osv.

Eksempler på uni-,bi- og trigrammer for setningen "Jeg liker å høste poteter ."

[('Jeg',), ('liker',), ('å',), ('høste',), ('poteter',), ('.',)]
[('Jeg', 'liker'), ('liker', 'å'), ('å', 'høste'), ('høste', 'poteter'), ('poteter', '.')]
[('Jeg', 'liker', 'å'), ('liker', 'å', 'høste'), ('å', 'høste', 'poteter'), ('høste', 'poteter', '.')]

Vi tar utgangspunkt i bruken til n-gram-metoden til NLTK. Den tar inn ei liste og et tall, slik:

ngrams(liste,tall)

...og gir oss setninger som i eksempelet over.

Merk at unigrammene ser "rare" ut fordi det er et komma der kun for å vise at det er et tuppel med ett element, det betyr ikke at det er to elementer hvorav ett er et tomt element.

Oppgave 1

Implementer en funksjon som tar inn ei liste, et tall (n) og returnerer ei liste med n-grammer som tupler. Hvis brukeren skriver et tall som er høyere enn antall elementer i lista, skal den returnere ei tom liste.

Oppgave 2

Gitt en vanlig liste med n-grammer har man ikke mulighet til å se hva som kommer først i setningen og hva som kommer midt i, men vi vet at noen ord og typer tegnsetting stort sett forekommer i starten eller slutten av en setning.

Skriv en funksjon padding(liste,tall) som tar inn ei liste og et tall, returnerer ei ny liste med tegnet "$" som padding på hver side av setningen.

Padding av "Jeg liker å høste poteter ." blir derfor:

['$', 'Jeg', 'liker', 'å', 'høste', 'poteter', '.', '$']

Oppgave 3

Kombiner funksjonene fra oppgave 1 og oppgave 2 i en ny funksjon, som tar inn en setning, n-gram-tallet, og antall elementer i padding: n_pad(setning,2,1) vil gi bigrammer (2) med én "$" på hver side (1). Test på teksten under. Teksten er tokenisert, men du må dele den opp. Hver setning skal behandles for seg. Skriv til slutt ut trigrammene til alle setningene i teksten med dobbel padding.

tekst = """En lang kamp for å heve statusen til kvensk språk har fått seg et lite løft .
Regjeringen har omsider starta et arbeid for å finne ut hva som må til for å løfte språket til nivå III i det europeiske språkcharteret .
Men sentrale myndigheter har vært skeptiske . Da kvensk blei anerkjent som eget språk i 2005 blei det vurdert .
Konklusjonen var da at man ikke ville være i stand til å oppfylle forpliktelsene det medfører ."""

Oppgave 4: Grubleoppgave

N-grammer brukes, som nevnt ovenfor, blant annet til å modellere sammenhengen mellom ord. Vi kan for eksempel få med sammenhengen mellom pronomen som kommer foran verb, og adjektiver foran substantiver, og mye mer, med bigrammer. Med trigrammer kan vi få med ting som artikler i lengre nomenfraser, så man kan lære at determinativ + adjektiv + substantiv er en vanlig sammensetning. Allikevel byr dette på problemer. En setning med 8 ord har 8 unigrammer uten padding. Hvor mange bigrammer har den? Hvor mange trigrammer?

Bruk n-gram-funksjonen uten padding til å telle ut hvor mange n-grammer det blir i spennet fra n=1 til n=10 i setninger som er 10 ord lange, inkludert tegnsetting. Skriv resultatene "pent" til terminalen. Hva ser du? Tror du det er lett for en statistisk basert modell å lære sammenhengen i lengre n-grammer?

Spørsmålet lar seg besvare utifra testen over, men hvis du vil ha en mer praktisk sjekk, så kan du ta en lengre tekst, og telle de mest frekvente n-grammene. Hva ser du der?

Vis løsningsforslag

Løsningsforslag

Oppgave 1

def ngram(liste,n):
    newlist = []
    for i in range(len(liste) - (n - 1)):
        newlist.append(tuple(liste[i:i+n]))
     return newlist

Eksempel på kjøring

setning = ['Jeg', 'liker', 'å', 'høste', 'poteter', '.']

print(ngram(setning,1))
print(ngram(setning,2))
print(ngram(setning,3))
print(ngram(setning,7))

>>>[('Jeg',), ('liker',), ('å',), ('høste',), ('poteter',), ('.',)]
>>>[('Jeg', 'liker'), ('liker', 'å'), ('å', 'høste'), ('høste', 'poteter'), ('poteter', '.')]
>>>[('Jeg', 'liker', 'å'), ('liker', 'å', 'høste'), ('å', 'høste', 'poteter'), ('høste', 'poteter', '.')]
>>>[]

Oppgave 2

def padding(liste,n):
    listekopi = liste[:] #for å slippe å endre den opprinnelige lista
    for i in range(n):
        listekopi.insert(0,"$")
        listekopi.append("$")
    return listekopi

Eksempel på kjøring:

setning = ['Jeg', 'liker', 'å', 'høste', 'poteter', '.']

print("Padding",padding(setning,1))
print("Padding",padding(setning,2))

Padding ['$', 'Jeg', 'liker', 'å', 'høste', 'poteter', '.', '$']
Padding ['$', '$', 'Jeg', 'liker', 'å', 'høste', 'poteter', '.', '$', '$']

Oppgave 3

def n_pad(setning,n,pad_n):
    nysent = padding(setning,pad_n)
    return ngram(nysent,n)

Eksempel på kjøring med teksten:

tekst = """En lang kamp for å heve statusen til kvensk språk har fått seg et lite løft .
Regjeringen har omsider starta et arbeid for å finne ut hva som må til for å løfte språket til nivå III i det europeiske språkcharteret .
Men sentrale myndigheter har vært skeptiske . Da kvensk blei anerkjent som eget språk i 2005 blei det vurdert .
Konklusjonen var da at man ikke ville være i stand til å oppfylle forpliktelsene det medfører ."""

setninger = tekst.split("\n")

for setning in setninger:
    setning = setning.split(" ")
    print(n_pad(setning,3,2))

Utskrift:

Ekstra linjeskift er satt inn mellom hver setning for å øke lesbarheten.

[('$', '$', 'En'), ('$', 'En', 'lang'), ('En', 'lang', 'kamp'), ('lang', 'kamp', 'for'), ('kamp', 'for', 'å'), ('for', 'å', 'heve'), ('å', 'heve', 'statusen'), ('heve', 'statusen', 'til'), ('statusen', 'til', 'kvensk'), ('til', 'kvensk', 'språk'), ('kvensk', 'språk', 'har'), ('språk', 'har', 'fått'), ('har', 'fått', 'seg'), ('fått', 'seg', 'et'), ('seg', 'et', 'lite'), ('et', 'lite', 'løft'), ('lite', 'løft', '.'), ('løft', '.', '$'), ('.', '$', '$')]

[('$', '$', 'Regjeringen'), ('$', 'Regjeringen', 'har'), ('Regjeringen', 'har', 'omsider'), ('har', 'omsider', 'starta'), ('omsider', 'starta', 'et'), ('starta', 'et', 'arbeid'), ('et', 'arbeid', 'for'), ('arbeid', 'for', 'å'), ('for', 'å', 'finne'), ('å', 'finne', 'ut'), ('finne', 'ut', 'hva'), ('ut', 'hva', 'som'), ('hva', 'som', 'må'), ('som', 'må', 'til'), ('må', 'til', 'for'), ('til', 'for', 'å'), ('for', 'å', 'løfte'), ('å', 'løfte', 'språket'), ('løfte', 'språket', 'til'), ('språket', 'til', 'nivå'), ('til', 'nivå', 'III'), ('nivå', 'III', 'i'), ('III', 'i', 'det'), ('i', 'det', 'europeiske'), ('det', 'europeiske', 'språkcharteret'), ('europeiske', 'språkcharteret', '.'), ('språkcharteret', '.', '$'), ('.', '$', '$')]

[('$', '$', 'Men'), ('$', 'Men', 'sentrale'), ('Men', 'sentrale', 'myndigheter'), ('sentrale', 'myndigheter', 'har'), ('myndigheter', 'har', 'vært'), ('har', 'vært', 'skeptiske'), ('vært', 'skeptiske', '.'), ('skeptiske', '.', 'Da'), ('.', 'Da', 'kvensk'), ('Da', 'kvensk', 'blei'), ('kvensk', 'blei', 'anerkjent'), ('blei', 'anerkjent', 'som'), ('anerkjent', 'som', 'eget'), ('som', 'eget', 'språk'), ('eget', 'språk', 'i'), ('språk', 'i', '2005'), ('i', '2005', 'blei'), ('2005', 'blei', 'det'), ('blei', 'det', 'vurdert'), ('det', 'vurdert', '.'), ('vurdert', '.', '$'), ('.', '$', '$')]

[('$', '$', 'Konklusjonen'), ('$', 'Konklusjonen', 'var'), ('Konklusjonen', 'var', 'da'), ('var', 'da', 'at'), ('da', 'at', 'man'), ('at', 'man', 'ikke'), ('man', 'ikke', 'ville'), ('ikke', 'ville', 'være'), ('ville', 'være', 'i'), ('være', 'i', 'stand'), ('i', 'stand', 'til'), ('stand', 'til', 'å'), ('til', 'å', 'oppfylle'), ('å', 'oppfylle', 'forpliktelsene'), ('oppfylle', 'forpliktelsene', 'det'), ('forpliktelsene', 'det', 'medfører'), ('det', 'medfører', '.'), ('medfører', '.', '$'), ('.', '$', '$')]

Oppgave 4

setning = "Denne lange setningen har hele ti ord i seg .".split(" ")

for i in range(1,11):
    print("Antall {}-grammer i setningen: {}".format(i,len(ngram(setning,i))))

Utskrift:

Antall 1-grammer i setningen: 10
Antall 2-grammer i setningen: 9
Antall 3-grammer i setningen: 8
Antall 4-grammer i setningen: 7
Antall 5-grammer i setningen: 6
Antall 6-grammer i setningen: 5
Antall 7-grammer i setningen: 4
Antall 8-grammer i setningen: 3
Antall 9-grammer i setningen: 2
Antall 10-grammer i setningen: 1

Man kan se at antallet mulige n-grammer synker etter hvert som n øker. I tillegg til at det er færre mulige tilfeller, vil man også kunne se at antallet like n-grammer synker drastisk for høyere tall. I en større tekstsamling kan vi finne ganske mange like bigrammer, men det er færre trigrammer som er like, og enda færre med høyere n. Det gjør at en eventuell statistisk modell ikke vil ha nok data til å klare å generalisere for veldig høye n-verdier.