Utforskning 9

Denne uken skal vi se på en ny datastruktur, dict, som er brukt ofte for å lagre strukturert data.

Eksempel 1

Her er et eksempel på en dictionary i Python. I dette eksemplet sier den hvilket husdyr ulike personer har.

pet = {
    "Alice": "Dog",
    "Bob": "Cat",
    "Claire": "Stick insect",
    "Dan": "Crocodile",
    "Eve": "Elephant",
    "Fred": "Dolphin",
}

Er navnene keys eller values i pet? Er dyrene keys eller values i pet? Hva gjør koden pet[‘Alice’]? Hva gjør koden pet[‘Xavier’] = ‘Alien’?

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

Hvorfor blir det feil i den siste linjen?

Eksempel 2

Vi kan bruke .keys(), .values() og .items() sammen med en for-løkke. Hva looper vi over når vi bruker en for-løkke med .keys()? Hva om vi bruker .values()? Hva om vi bruker .items()?

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}")

Hva skjer i den siste løkken?

Eksempel 3

Metoden .get() brukes til å finne ut verdien til en gitt nøkkel. Forskjellen mellom .get() og å bruke [] er at vi ikke får KeyError om nøkkelen ikke finnes da vi bruker .get().

pet = {
    "Alice": "Dog",
    "Bob": "Cat",
    "Claire": "Stick insect",
    "Dan": "Crocodile",
    "Eve": "Elephant",
    "Fred": "Dolphin",
}

print(pet.get("Dan"))
print(pet.get("Karl"))  # we don't get KeyError here
print(pet.get("Karl", "Sloth"))  # we can specify the value if the key doesn't exist

Skjønner du hva som skjer?

Eksempel 4

Vi kan bruke alle ’immutable data types’ som keys i en dictionary. Husker du hvilke datatyper er immutable? I eksemplet her bruker vi heltall og strenger.

 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)

Hva gjør koden? Hvordan ser number_name ut på slutten av kjøringen?

Eksempel 5

Metoden .setdefault() returnerer verdien til en gitt nøkkel om den finnes i dictionarien. Om den ikke finnes så putter den inn en slik nøkkel med enten verdien None eller med en verdi vi gir, og returnerer så verdien som er blitt satt inn. Du kan lese om .setdefault() i Pythons dokumentasjon.

Se om du skjønner du hva som skjer før du kjører koden?

pet = {
    "Alice": "Dog",
    "Bob": "Cat",
    "Claire": "Stick insect",
    "Dan": "Crocodile",
    "Eve": "Elephant",
    "Fred": "Dolphin",
}

val_1 = pet.setdefault("Claire", "Rhino")
print(f"{val_1 = }")
print(f"{pet = }")

val_2 = pet.setdefault("Gunnar", "Parrot")
print(f"{val_2 = }")
print(f"{pet = }")

val_3 = pet.setdefault("Harriet")  # the default value is None
print(f"{val_3 = }")
print(f"{pet = }")
Eksempel 6

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’.

. Skjønner du hva som skjer i koden nedenfor? 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.

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")

Husk at du kan bruke søkeordargumenter med funksjonene dine og Pythons innbygde funksjoner, f.eks sorted() Eksemplen nedenfor er med lister, men du kan også bruke med dictionarys. Se også i koden over på variabelen sorted_result – dette er en smart bruk av søkeordargumenter for å sortere dictionarien din.

names = ["Alice", "Bob", "Claire", "Dan", "Eve", "Fred"]

# sort names by length
sorted_names = sorted(names, key=len)

print(sorted_names)
Eksempel 7

En relatert datatype er set, som er en usortert samling av elementer. Vi kan konstruere dem i Python med {} eller set(). I mengder finnes det kun én av hvert verdi og det finnes ingen orden mellom verdiene.

Vi kan gjøre samme ting med mengder i Python som vi kan i mengdelære i matematikk. For eksempel kan vi finne ut unionen (elementer som finnes i én eller begge set), snittet (elementer som er felles) og differensen (elementer som ikke finnes i det andre set) mellom mengder, eller om en mengde er en delmengde av en annen mengde.

Skjønner du hva som skjer i koden nedenfor?

animals_1 = {"dog", "cat", "stick insect", "crocodile", "elephant", "dolphin"}
animals_2 = {
   "stick insect",
   "dolphin",
   "cat",
   "sloth",
   "dolphin",
}  # duplicates are ignored

print(f"{animals_1 = }")  # order is ignored
print(f"{animals_2 = }")  # order is ignored

animals_2.add("gorilla")  # we can add an element to the set
print(f"{animals_2 = }")

animals_3 = set(["cat", "elephant"])  # we can also construct sets using set()
print(f"{animals_3 = }")
print()

################################################################################

print(f"{animals_2.union(animals_3) = }")  # the union of animals_2 and animals_3

print(
   f"{animals_1.intersection(animals_2) = }"
)  # the intersection of animals_1 and animals_2

print(f"{animals_1.difference(animals_2) = }")  # animals_1 - animals_2

print(f"{animals_2.issubset(animals_1) = }")  # is animals_2 a subset of animals_1?
print(f"{animals_3.issubset(animals_1) = }")  # is animals_3 a subset of animals_1?

################################################################################

# we can turn a list into a set and then bac