Uke 9 - Dict¶
Denne uken skal vi se på en ny datastruktur, dict, som er brukt ofte for å lagre strukturert data.
Først, les gjennom https://automatetheboringstuff.com/2e/chapter5/ frem til «Pretty Printing», og se på «Practice Questions 1-7»
Eksempler¶
Eksempel 1¶
Her er et eksempel på en dictionary i Python. I dette eksemplet sier den hvilket husdyr ulike personer har.
Last ned filen her: eksempel_2.py
, og kjør koden. Er navnet ’keys’ eller
’values’ i pet
? Er dyret ’keys’ eller ’values’ i pet
?
Hva gjør koden pet['Alice']
? Hva gjør koden pet['Xavier'] = 'Alien'
? Hvorfor
blir det feil i den siste linjen?
pet = {
'Alice' : 'Dog',
'Bob' : 'Cat',
'Claire' : 'Stick insect',
'Dan' : 'Crocodile',
'Eve' : 'Elephant',
'Fred' : 'Dolphin'
}
print('All pets',pet)
print(pet['Alice'])
print(pet['Eve'])
pet['Xavier'] = 'Alien'
print(pet)
print(pet['Karl']) # KeyError
Eksempel 2¶
Vi kan bruke .keys()
, .values()
og .items()
sammen med en for-løkke.
Last ned filen her: eksempel_3.py
, og kjør koden.
Hva looper vi over når vi bruker en for-løkke med .keys()
? Hva om vi bruker
.values()
? Hva om vi bruker .items()
?
Hva skjer i den siste løkken?
pet = {
"Bob": "Cat",
"Fred": "Dolphin",
"Dan": "Crocodile",
"Claire": "Stick insect",
"Alice": "Dog",
"Eve": "Elephant",
}
print("All owners")
for name in pet.keys():
print(name)
print("\n\n\n")
print("All pets")
for animal in pet.values():
print(animal)
print("\n\n\n")
print("All pairs")
for p in pet.items():
print(p)
print("\n\n\n")
print("Unpack the pair tuple")
for name, animal in pet.items():
print(f"{name} has a pet, and it is a {animal}")
Eksempel 3¶
Vi kan bruke alle ’immutable data types’ som keys i en dictionary. Husker du hvilke datatyper er immutable?
I eksemplet her bruker vi heltall.
Last ned filen her: eksempel_4.py
. Hva gjør koden?
Kjør koden og se om det var riktig.
Hvordan ser number_name
ut på slutten av kjøringen?
number_name = {
0 : 'zero',
1 : 'one',
2 : 'two',
3 : 'three',
12: 'twelve',
10: 'ten',
}
def print_name(n):
if n in number_name:
print(f'{n} is called {number_name[n]}')
else:
print(f"I don't know what {n} is called.")
name = input("Please tell me: ")
number_name[n] = name
print_name(3)
print_name(56)
print_name(2)
print_name(56)
Eksempel 4¶
En dictionary kan f.eks brukes for å holde rede på hvor mange vi har av forskjellige ting. Her bruker vi dictionaries til å telle hvor mange ganger vi bruker ulike bokstaver og ord i begynnelsen av ’Alice in Wonderland’.
Last ned filen her: eksempel_5.py
, og kjør koden. Skjønner du hva som
skjer? Hva gjør .setdefault()
? (Du kan lese om den
i Pythons dokumentasjon.)
I slutten av koden finner vi de 5 vanligste ordene. Prøv å bruk ’option 2’ i stedet.
Som vanlig kan du finne informasjon om hvordan sorted()
fungerer
i Pythons dokumentasjon.
Obs
Husk fra den forrige uken at du kan bruke søkeordargumenter med funksjonene dine
og Pythons innbygde funksjoner, f.eks sorted()
Last ned filen her: eksempel_1.py
, og kjør koden. Denne eksemplen er
med lister, men du kan også bruke med dictionarys.
names = ['Alice', 'Bob', 'Claire', 'Dan', 'Eve', 'Fred']
# sort names by length
sorted_names = sorted(names, key=len)
print(sorted_names)
Se også i koden på variabelen sorted_result
– dette er en smart bruk av søkeordargumenter for å sortere dictionarien din.
text = """Alice was beginning to get very tired of sitting by her sister
on the bank, and of having nothing to do: once or twice she had peeped
into the book her sister was reading, but it had no pictures
or conversations in it, 'and what is the use
of a book,' thought Alice 'without pictures or conversation?'"""
letter_count = {}
for l in 'abcdefghijklmnopqrstuvwxyz':
letter_count[l] = 0
for let in text:
let = let.lower()
if let in letter_count: # check if key exists in dict
letter_count[let] += 1
for let, count in letter_count.items():
print(f'{let} is used {count:3d} times')
print('\n\n\n')
word_count = {}
for word in text.split():
word = word.lower()
word_count.setdefault(word, 0)
word_count[word] += 1
for w, count in word_count.items():
print(f'{w:14} is used {count:3d} times')
print('\n\n\n')
# The 5 most used words
# need to sort by the value in the (key,value) tuple
# option 1
def get_second(tpl):
"""Return the second element"""
return tpl[1]
# using the keyword arguments of sorted() to sort by the second value and in reverse
sorted_result = sorted(word_count.items(), key=get_second, reverse=True)
# option 2, python has "get_second" built-in as "itemgetter"
#from operator import itemgetter
#sorted_result = sorted(word_count.items(), key=itemgetter(1), reverse=True)
print('The 5 most common words')
for w, c in sorted_result[:5]:
print(f'{w:14} is used {c:3d} times')
Oppgaver¶
Oppgave 1¶
Lag en handleliste og print den. Handlelisten skal være en dict med varer som keys og antall som values. Varene er:
2 brød
3 pizza
10 poteter
1 kaffe
1 ost
14 epler
Skriv ut dictionarien:
{'brød': 2, 'pizza': 3, 'poteter': 10, 'kaffe': 1, 'ost': 1, 'epler': 14}
Oppgave 2¶
I denne oppgaven skal vi jobbe med my_dict
og my_list
definert her:
my_dict = {
0 : 0,
1 : "vafler",
"two" : 2,
5 : 4
}
my_list = [0, 1, "boller", 4]
Skriv ut nøklene, verdiene og nøkkel/verdi-par for my_dict
,
og listeverdiene og index/verdi par for my_list
.
Eksempelkjøring:
Dictionary Keys:
0
1
two
5
Dictionary Values:
0
vafler
2
4
Dictionary keys/value:
0 0
1 vafler
two 2
5 4
List values:
0
1
boller
4
List indices/value:
0 0
1 1
2 boller
3 4
Oppgave 3¶
Vi ser for oss at følgende dictionary representerer varebeholdningen i en bokhandel. Nøklene er titler og verdiene er antall bøker:
in_storage = {
"Ancillary Justice": 1_046, # vi kan bruke _ i tall, den blir ignorert
"The Use of Weapons": 372,
"1984": 5_332,
"The Three-Body Problem": 523,
"A Fisherman of the Inland Sea": 728,
}
Spør brukeren om en boktittel og bruk .get()
for å finne ut hvor mange eksemplarer
av boka vi har. Hvis boka ikke er på lager skal du skrive ut 0. Kjør løkken frem til
vi får en tom streng som tittel.
Eksempelkjøring:
Tittel: 1984
Vi har 5332 av "1984"
Tittel: A Fire Upon the Deep
Vi har 0 av "A Fire Upon the Deep"
Tittel: Automate the Boring Stuff with Python
Vi har 0 av "Automate the Boring Stuff with Python"
Tittel:
Ha det!
Oppgave 4¶
Bruk funksjonen collatz_sequence
fra uke 8 oppgave 2 til å lage en dictionary
med tallene 1-10 som keys og Collatz-sekvensen som verdi. Print resultatet.
Her er én løsning på collatz_sequence
:
def collatz_sequence(n):
sequence = [n]
while n > 1:
if n % 2 == 0:
n = n // 2
else:
n = 3*n + 1
sequence.append(n)
return sequence
Eksempelkjøring:
{1: [1], 2: [2, 1], 3: [3, 10, 5, 16, 8, 4, 2, 1], 4: [4, 2, 1], ...}
Oppgave 5¶
I denne oppgaven skal vi gjøre det samme som i oppgave 3, men litt annerledes.
Hvis brukeren spør om en bok som ikke er på lager skal vi «kjøpe inn» 10 og
legge til boka i in_storage
med 10 eksemplarer.
Eksempelkjøring:
Tittel: 1984
Vi har 5332 av "1984"
Tittel: Automate the Boring Stuff with Python
Vi har 10 av "Automate the Boring Stuff with Python"
Tips: bruk setdefault()
Oppgave 6¶
I denne oppgaven skal vi bruke en dictionary med informasjon om biler:
cars = {
"Escort" : {
"Brand": "Ford",
"Horsepower": 200,
"Wheels": 4,
"Color": "red"
},
"Beetle" : {
"Brand": "Volkswagen",
"Horsepower": 120,
"Wheels": 4,
"Color": "blue"
},
"Isetta" : {
"Brand": "BMW",
"Horsepower": 50,
"Wheels": 3,
"Color": "green"
},
}
Bruk dette til å skrive ut merket, modellnavn, antall hjul, hestekrefter og farge for hver bil.
Eksempelkjøring:
The Ford Escort has:
4 wheels, 200 horsepowers, and is red
The Volkswagen Beetle has:
...
Oppgave 7¶
Fantasy Game Inventory fra boken (https://automatetheboringstuff.com/2e/chapter5/)
Du lager et fantasy-videospill. Datastrukturen for å modellere spillerens beholdning skal være en dictionary hvor nøklene er strings som beskriver tingene i beholdningen, og verdiene er integers som forteller hvor mange av hver ting som spilleren har. For eksempel, verdiene i dictionary
{'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}
betyr at spilleren har 1 rope, 6 torches, 42 gold coins, etc.
Begynne med filen uke09_oppgave_7.py
og skriv resten av funksjonen displayInventory()
som tar inn alle mulige beholdningene og printer dem som nedenfor. Funksjonen
skal også returnere totalt antall.
Eksempelkjøring:
Inventory:
1 rope
6 torch
42 gold coin
1 dagger
12 arrow
Total number of items: 62
Oppgave 8¶
Dragon Hoard fra boken (https://automatetheboringstuff.com/2e/chapter5/)
Skatten til en beseiret drage er representert som en liste med strenger som dette:
dragonLoot = ['gold coin', 'dagger', 'gold coin', 'gold coin', 'ruby']
Fyll inn funksjonen som heter
addToInventory(inventory, addedItems)
, hvorinventory
parameteren er en dictionarien av spillerens beholdning ogaddedItems
parameteren er en liste som f.eksdragonLoot
.
addToInventory()
funksjonen burde returnere en dictionary som representerer den oppdaterte beholdningen. Merk at listen over tilleggsartikler kan inneholde flere av samme element.
Begynne med filen uke09_oppgave_8.py
og skriv resten av funksjonen som heter addToInventory
.
Om du kaller displayInventory()
etter å ha oppdatert beholdingen med
addToInventory()
funksjonen skal du få ut likt som nedenfor:
Eksempelkjøring:
Inventory:
45 gold coin
1 rope
1 dagger
1 ruby
Total number of items: 48
Oppgave 9 - Euler 17¶
https://projecteuler.net/problem=17
If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of «and» when writing out numbers is in compliance with British usage.
Skriv en funksjon number_name(N) som tar inn et heltall (opp til 1000) som
argument N
og returnerer det engelske navnet til tallet som en streng.
Tips: begynn med dict’et som finnes i eksempel 3, og legge inn flere tall der. Du trenger ikke å ta med alle tallene frem til 1000, siden de fleste kan settes sammen. Gjerne bruk flere funksjoner for å organisere programmet
Skriv en funksjon all_numbernames(N) som tar inn et heltall (opp til 1000) som argument N og returnerer den summerte lengden av alle navnene fra 1 til N (sjekk eksemplene fra Euler-teksten). Du kan gjenbruke number_name() her.
Skriv en funksjon solve_euler_17() som returnerer den summerte lengden av alle navnene fra 1 til 1000. Du kan gjenbruke de andre funksjonene.