Uke 6 - list¶
Les https://automatetheboringstuff.com/2e/chapter4/ frem til «EXCEPTIONS TO INDENTATION RULES IN PYTHON»-boksen.
Eksempler¶
Denne uken skal vi se på noen eksempler på lister og hva man kan gjøre med dem.
Eksempel: Basics¶
Last ned filen her: eksempel_basic_lists.py
og kjør koden. Prøv å endre i
listene og se hva som skjer.
a = [5, 7, 2, 9, 10]
print(a, len(a))
if 9 in a:
print(f"9 is in the list a = {a}!")
b = [5, "str", 9.3]
print("Lists can have mixed types inside:", b)
c = a + b
print(f"We can concatenate lists: c = {c}")
x, y, z = [1, 5, 7]
print(x)
print(y)
print(z)
Eksempel: Lister av lister¶
Lister kan også inneholde andre lister. Da må vi bruke to tall for å indeksere dem.
Last ned eksempelet her eksempel_2D_lists.py
. Hva tror du den vil skrive ut?
Var det riktig?
a = [["A", "B"], ["C", "D"]]
print(f"The list a: {a}")
print(f"a[0] = {a[0]}")
print(f"a[0][1] = {a[0][1]}")
# Hva er a[0][0]?
# Hva er a[1][0]?
print()
b = [[1], [1,2], [1,2,3]]
print(f"The list b: {b}")
print(f"b[2] = {b[2]}")
print(f"b[2][1] = {b[2][1]}")
# Hva skjer om du skriver b[1][2]?
print()
for row in b:
for n in row:
print(n, end="")
print()
Lister av lister kalles ofte 2-dimensjonale (2D) lister fordi du kan tenke på dem som et 2D koordinatsystem:
grid = [["00", "01", "02"],
["10", "11", "12"],
["20", "21", "22"]]
Eksempel: Listefunksjoner¶
Her er noen ulike metoder man kan bruke på lister. Du kan finne ut mer på https://docs.python.org/3/tutorial/datastructures.html
Last ned filen her: eksempel_list_functions.py
og kjør koden. Skjønner du hva
som skjer? Prøv de ulike metodene selv.
# https://docs.python.org/3/tutorial/datastructures.html
a = [5, 7, 2, 9, 10]
print(f"a = {a}")
# .append()
a.append(7)
print(f"We append 7: {a}")
# .insert()
a.insert(2, 6)
print(f"We insert 6 at index 2: {a}")
# .reverse()
a.reverse()
print(f"We reverse a: {a}")
# .remove()
a.remove(7)
print(f"We remove the first occurence of 7: {a}")
# .sort()
a.sort()
print(f"We sort a: {a}")
Eksempel: Input i lister¶
I dette eksemplet spør vi brukeren om positive tall, og siden beregnes maksimum av tallene på to måter.
Last ned filen her: eksempel_input.py
og kjør koden. Skjønner du hvordan
while-løkken fungerer? Hvordan blir den avsluttet? Hva gjør den siste raden i den
løkken? Om du er usikker kan du gå igjenom noen iterasjoner av løkken med papir
og penn og se hva som skjer.
Skjønner du hvordan for-løkken fungerer?
# ask for several numbers
# store in list
# find maximum
nums = []
while True:
n = input("A positive number (q to stop): ")
if n == "q":
break
n = int(n)
if n < 0:
print("That was negative. Try again")
continue
nums.append(n)
print(f"You gave me {len(nums)} numbers.")
print("Your numbers are:", nums)
print("The maximum number is:", max(nums))
print("Doing max by hand...")
maxnum = 0
for num in nums:
if num > maxnum:
maxnum = num
print("My own max is:", maxnum)
I dette eksemplet lagrer vi tallene fra brukeren i en liste. Det er fordi vi ikke vet hvor mange tall vi kommer til å få fra brukeren. En liste i Python kan vi gjøre så lang som vi trenger. Vi må ikke vite på forhånd hvor lang den skal være.
Eksempel: Strings og lister¶
Her er noen eksempler på metodene split()
og join()
.
Last ned filen her: eksempel_strings.py
og kjør koden. Hvordan fungerer split()
?
Hvordan fungerer join()
? Hva gjør for-løkken?
text = "Alice was beginning to get very tired"
print(text)
words = text.split()
print(words)
print(len(words),'words')
weird = text.split('t')
print(weird)
joined = '==='.join(words)
print(joined)
nospaces = ''.join(words)
print(nospaces)
print()
print('Lines of 3 words each:')
line = []
for w in words:
if len(line) < 3:
line.append(w)
else:
print(' '.join(line))
line = [w] # start next line
print(' '.join(line))
Eksempel: Enumerate¶
Her er et eksempel på metoden enumerate()
. Med enumerate()
i en for-løkke
får man ikke bare elementene i listen, men man får også indeksen for elementene.
Last ned filen her: eksempel_enumerate.py
og kjør koden. Skjønner du hva som
skjer? Kan du endre koden til å ikke bruke enumerate()
?
animals = ['dog','cat','bird']
for index, animal in enumerate(animals):
print(index, animal)
Eksempel: List Comprehension¶
Her er et eksempel på list comprehension (listeinklusjon). Dette er veldig lett og rask måte å lage nye lister fra verdiene til en eksisterende liste. Sammenlign eksemplene nedenfor og forklar forskjellene til en venn.
animals = ['dog', 'elephant', 'bird']
# create new list with a for-loop
lengths = []
for a in animals:
lengths.append(len(a))
print(lengths)
# do the same thing using list comprehension
lengths = [len(a) for a in animals]
print(lengths)
# for-loop
xs = [-4, 1, 3, 7, 10, 12]
ys = []
for x in xs:
ys.append(x**2 - 2*x + 1)
print(ys)
# do the same thing using list comprehension
ys = [x**2 - 2*x + 1 for x in xs]
print(ys)
Leseforståelse: Polynomer¶
I dette eksempelet lager vi en funksjon poly_string()
som gjør den samme ting
som funksjonen med samme navn i oppgave 1, uke 4, men med forskjellen at funksjonen
tar en liste med koeffisienter som argument, sånn at polynomet kan være av hvilken
grad som helst.
Vi lager også en funksjon poly_val()
som beregner verdien av et polynom
i en punkt. Argumenten til funksjonen er en liste med koeffisienter og et tall.
Kan du forstå hva programmet gjør uten å kjøre det?
Last ned filen her: eksempel_poly.py
.
# Example of enumerate:
# printing polynomials,
# calculating values of polynomials
def poly_val(coeffs, x):
"""Calculate value of polynomial at a point
coeffs: a list of non-negative integer coefficients of a polynomial
sorted from lowest degree to highest degree
x: a float, the point at which to evaluate the polynomial
"""
sum = 0
for i, coe in enumerate(coeffs):
sum += coe * x ** i
return sum
def poly_string(coeffs):
"""Give a string representation of a polynomial
coeffs: a list of non-negative integer coefficients of a polynomial
sorted from lowest degree to highest degree
"""
terms = []
if coeffs: # Adding the constant term
coe = coeffs[0]
if coe != 0:
terms.append(str(coe))
coeffs = coeffs[1:]
if coeffs: # Adding the linear term
coe = coeffs[0]
if coe == 1:
terms.append("x")
elif coe > 1:
terms.append(f"{coe}x")
coeffs = coeffs[1:]
if coeffs: # Adding all other terms
for i, coe in enumerate(coeffs):
if coe == 1:
terms.append(f"x^{i+2}")
elif coe > 1:
terms.append(f"{coe}x^{i+2}")
if not terms: # If we were given an empty list or only zeros
return "0"
else:
terms.reverse()
return " + ".join(terms)
# Give a list of coefficients sorted from highest to lowest degree
# (as in exercise 1, week 4).
coeffs = [6, 12, 0, 1, 5] # 6x^4 + 12x^3 + x + 5
x = 2
coeffs.reverse()
print(f"The value of {poly_string(coeffs)} at {x = } is {poly_val(coeffs, x)}.")
Eksempel: in
¶
Her er et eksempel på bruk av in
i en for-løkke.
Last ned filen her: eksempel_in.py
. Før du kjør koden, hva tror du output blir?
Kjør koden. Var det riktig?
# This code should tell a visitor entering a museum what
# they must pay, depending on whether the visitor is a
# senior, a student or none of the above. Try some different values.
def ticket_price(visitor_type):
"""Calculate the ticket price based on visitor category.
visitor_type: a list of categories
"""
if "senior" in visitor_type:
return 80
elif "student" in visitor_type:
return 90
else:
return 100
alice = ["student", "senior"]
bob = []
carol = ["senior"]
dan = ["student"]
visitors = [alice, bob, carol, dan]
for v in visitors:
price = ticket_price(v)
print(f"{v} has to pay kr.{price}.")
Kan du endre koden slik at navnene blir skrevet ut (bruk en liste til)?
Eksempel: Feil¶
Her er et eksempel på ting som kan gå galt med lister.
Last ned filen her: errors_1.py
. Før du kjør koden, se om du finner alle feil.
Prøv å kjøre koden. Endre sånn at koden går å kjøre.
a = ["xyz", "abc", 5.4, "z", True, 7, "Hei there"]
length = len(a)
print(a[length])
b = [12, 34, 1, 107, "14", 16, 19]
b.sort()
print(b)
#####
print("Returning coins:")
coins = [1, 5, 10, 20]
price = 24
payment = 50
# work out return coins
diff = payment - price
for c in coins:
while diff > c:
print(f"Returning kr.{c}")
diff -= c
Koden i slutten skal beregne vekslepenger som skal returneres ved en betaling. Det finnes 20-kr, 10-kr, 5-kr og 1-kr. Den skal returnere slik at man får så få mynter som mulig. For eksempel, om prisen er 24 kr og betalingen er 50 kr skal den returnere én 20-kr, én 5-kr og én 1-kr. Men noe er feil med koden sånn at den ikke gjør helt som den skal. Kan du endre sånn at den fungerer som den skal?
Ekstra øving:¶
For å sjekke hva du har lært kan du gjøre ’practice questions’ 1-10 i kapittel 4 i Automate the Boring Stuff.
Oppgaver¶
Oppgave 1¶
I oppgave_1.py
skriv en while
-løkke som fjerner alle
7-tallene fra listen numbers
. Skriv ut resultat-listen. Husk at
med while-løkker trenger du tre ting: (1) start, (2) test, og
(3) update.
numbers = [0, 7, 97, 7, 5, 7, 20, 11]
Oppgave 2¶
I oppgave_2.py
skriv en ny list fra mylist
nedenfor.
Bruk slice-notasjon til å skrive ut annethvert element i
listen fra 1 til 6.
mylist = ['a', 1, 'b', 'c', 2, 6, 'g']
Oppgave 3¶
I oppgave_3.py
snu rekkefølgen på listen nedenfor
(dette er den samme listen som oppgave 2). Bruk slice
-notasjon.
Skriv ut resultat-listen.
mylist = ['a', 1, 'b', 'c', 2, 6, 'g']
Oppgave 4¶
I oppgave_4.py
bruk enumerate()
for å skrive ut en
ny streng med alle bokstaver på partalls-indeks
fra ordet bryggeriet
.
Oppgave 5¶
I oppgave_5.py
gjør det samme som i oppgave 4, men denne
gangen bruk listeinklusjon (list comprehension).
Oppgave 6¶
I oppgave_6.py
skriv ut en ny liste som dobler listen nedenfor:
mylist = [1,2,3,4]
Tips: Bruk append()
metoden eller comprehension
Oppgave 7¶
I oppgave_7.py
skriv ut en liste som bare inneholder unike verdier fra listen nedenfor:
mylist = [1,1,1,1,2,2,3,3,3,3,4,4,4,5,5]
Skriv også ut lengden til lista med unike verdier.
Eksempelkjøring:
[1, 2, 3, 4, 5]
5
Tips: Du kan bruker enten append() med en ny liste eller remove() med den opprinnelige listen.
Oppgave 8¶
Fra boka: Tenk deg at du du har en liste av lister der hvert element i den indre listene er en streng med én bokstav, slik:
Eksempelkjøring:
grid = [['.', '.', '.', '.', '.', '.'],
['.', 'O', 'O', '.', '.', '.'],
['O', 'O', 'O', 'O', '.', '.'],
['O', 'O', 'O', 'O', 'O', '.'],
['.', 'O', 'O', 'O', 'O', 'O'],
['O', 'O', 'O', 'O', 'O', '.'],
['O', 'O', 'O', 'O', '.', '.'],
['.', 'O', 'O', '.', '.', '.'],
['.', '.', '.', '.', '.', '.']]
Tenk på grid[x][y] som karakteren i posisjon (x,y) i et «bilde» tegnet med bokstaver. Origo, (0,0), er oppe til venstre, x-koordinatene øker til høyre og y-koordinatene øker nedover.
Kopier grid-listen og skriv kode som bruker listen til å printe dette «bildet»:
Eksempelkjøring:
..OO.OO..
.OOOOOOO.
.OOOOOOO.
..OOOOO..
...OOO...
....O....
Hint: Du vil trenge en loop i en loop for å kunne printe grid[0][0], grid[1][0], grid[2][0], osv., opp til grid[8][0]. Dette vil være første rad, og må avsluttes med en newline. Deretter skal neste rad printe grid[0][1], grid[1][1], grid[2][1], osv. Det siste koden din skal printe er grid[8][5].
Husk også at print() automatisk avslutter med en et nylinje argument, så du må enten gi inn et annent slutt argument eller bygge opp hele raden før du skriver den ut.
Oppgave 9¶
Skriv din egen versjon av den innbygde funksjonen len
, med navnet my_len
.
Den skal returnere lengden av en liste eller en streng, slik som len
.
Du kan ikke kalle på andre funksjoner inne i my_len
.
Eksempelkjøring:
>>> my_len([])
0
>>> my_len("123")
3
OBS: Her vises funksjonen i interaktiv modus med funksjonskallet på én linje og returverdien på den neste. Du trenger ikke å printe noe som helst.
Oppgave 10: DNA-komplementstreng¶
En DNA-sekvens (f.eks ATAGCAGT
) sammensettes av 4 ulike «baser»,
som beskrives med A
, T
, G
og C
.
Under replikasjon av sekvensen kan hver base settes sammen med
eksakt én av de andre. A
med T
, og C
med G
:
original ------->
ATAGCAGT
||||||||
TATCGTCA
<------- complement
Slik får man en «komplementstreng» av den opprinnelige DNA-sekvensen.
Det vanlig å skrive ned komplementstrenger baklengs,
slik at i vårt eksempel, vi sier at ATAGCAGT
og ACTGCTAT
er komplementstrenger av hverandre.
I oppgave_10.py
lag en funksion complement
som returnerer komplementstrengen av en
DNA-sekvens. Funksjonen skal ta inn én streng som argument, og skal returnere
én streng. Du kan anta at alle input-strenger er gyldige DNA-sekvenser.