More on Lists¶
Data¶
string
integer / float
list
2D arrays zijn lijsten van lijsten, LoL’s
Lists¶
Lists zijn containers, ze bevatten verwijzingen naar data
my_list = [5, 42, "hi"]

Indentiteit¶
help(id)
Help on built-in function id in module builtins:
id(obj, /)
Return the identity of an object.
This is guaranteed to be unique among simultaneously existing objects.
(CPython uses the object's memory address.)
Het geheugenadres van my_list
id(my_list)
140133778384640
De geheugenadressen van de elementen van L
id(my_list[0]) # 5
140133910222792
id(my_list[1]) # 42
140133910223976
id(my_list[2]) # "hi"
140133910266656
Waarde en identiteit¶
a = "Astronaut wordt snel oud tijdens een reis naar Mars"
b = "Astronaut wordt snel oud tijdens een reis naar Mars"
a == b
True
a is b
False
id(a)
140133780070800
id(b)
140133780071472
Verwijzingen¶
by reference
Lists bevatten verwijzingen naar geheugenadressen, niet de waarden zelf!
by value
Getallen en strings verwijzen naar de waarde
Mutabiliteit¶
mutable (veranderlijk)
Lists kunnen worden aangepast
immutable (onveranderlijk)
Getallen en strings kunnen niet worden aangepast
Mutable¶
Lists
my_list = [11, 21]
id(my_list)
140133778435776
my_list[0] = 42
id(my_list)
140133778435776
my_list
[42, 21]
Immutable¶
Strings en getallen
string = "hallo "
id(string)
140133778474496
string += "wereld"
id(string)
140133778465904
number = 10
id(number)
140133910222952
number += 1
id(number)
140133910222984
Data die zelf iets doet¶
Tot nu toe deed jij iets met data. De functie staat vooraan en de data gaat erin:
len(my_list)
sum(my_list)
my_list + [9]
Vanaf nu zie je het ook andersom:
my_list.append(9)
Hier staat de lijst vooraan en de handeling erachter. Je vraagt niet aan een functie om iets met de lijst te doen; je vraagt het aan de lijst zelf.
Zo’n handeling die bij de data zelf hoort heet een methode. Je schrijft hem met een punt: eerst het ding, dan de punt, dan wat het moet doen.
my_list = [11, 21]
my_list.append(42)
my_list
[11, 21, 42]
Let op wat er niet gebeurt: er komt geen nieuwe lijst uit. append geeft niets
terug, hij verandert de lijst die er al was.
my_list = [11, 21]
resultaat = my_list.append(42)
print(resultaat)
None
None, dus. Dit is dezelfde mutatie als hierboven met my_list[0] = 42, alleen
anders opgeschreven.
Daarmee heb je twee manieren om er een element bij te zetten:
Wat er gebeurt |
Schrijfwijze |
|---|---|
Er komt een nieuwe lijst |
|
De lijst zelf verandert |
|
Allebei goed. Wanneer het verschil uitmaakt zie je zo meteen.
Neem dit voorlopig aan
Waaróm data zelf iets kan doen, leer je in Programmeren 2. Daar maak je ze zelf: data met handelingen eraan vast, en zoiets heet een object.
Voor nu is het een schrijfwijze die je moet herkennen en kunnen gebruiken. Je komt hem overal tegen, want vrijwel alles in Python werkt zo, en dat is ook de reden dat je hem nu al nodig hebt.
Functies?¶
by copy
Functies ontvangen parameters als kopie
def fav(x):
print("fav VOOR: x is", id(x), "en heeft de waarde x", x)
x = "Pizza quattro formaggi"
print("fav NA: x is", id(x), "en heeft de waarde x", x)
def main():
y = "Pizza salami ananas" # bah
print("main VOOR: y is", id(y), "en heeft de waarde", y)
fav(y)
print("main NA: y is", id(y), "en heeft de waarde", y)
main()
main VOOR: y is 140133778504688 en heeft de waarde Pizza salami ananas
fav VOOR: x is 140133778504688 en heeft de waarde x Pizza salami ananas
fav NA: x is 140133778501488 en heeft de waarde x Pizza quattro formaggi
main NA: y is 140133778504688 en heeft de waarde Pizza salami ananas
Shallow versus deep copy¶
De ene kopie is de andere niet!
Shallow copy¶
Assignment statements in Python do not copy objects, they create bindings between a target and an object.
Wat create bindings hier betekent laten we in het midden, duidelijk is dat geen kopie wordt gecreëerd maar iets van een verwijzing die later eenvoudig te verbreken valt.
x = "regen"
y = x
x is y
True
y = "zonneschijn"
x is y
False
print("Na", x, "komt", y)
Na regen komt zonneschijn
Lists en shallow copy¶
my_list = [5, 42, "hi"]
your_list = my_list
your_list[0] = 60
your_list[0]
60
my_list[0]
60
Lists zijn mutable en de shadow copy M verwijst nog steeds naar L en een aanpassing van M zal niet leiden tot een nieuwe list (zoals je wel zag gebeuren bij strings en integers).
Deep copy¶
Deep copy is alleen relevant voor containertypes als lists!
A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
Een deep copy creëert een nieuwe container, eventuele wijzigingen zijn vervolgens alleen van toepassing op de kopie, niet het origineel.
from copy import deepcopy
my_list = [5, 42, "hi"]
your_list = deepcopy(my_list)
your_list is my_list
False
your_list[0] = 60
Wat is de waarde van my_list[0]?
my_list[0]
5
Slicing is ook diep!¶
my_list = [5, 42, "hi"]
your_list = my_list[:]
your_list[0] = 60
my_list[0]
5
Quiz¶
Vraag 1¶
def conform1(fav):
fav = 42
return fav
def main1():
fav = 7
conform1(fav)
print(fav)
Wat wordt geprint voor fav in de functie main1?
Antwoord¶
main1()
7
Vraag 2¶
def conform2(lst):
lst = [42, 42]
return lst
def main2():
lst = [7, 11]
conform2(lst)
print(lst)
Wat wordt geprint voor lst in de functie main2?
Antwoord¶
main2()
[7, 11]
Vraag 3¶
def conform3(lst):
lst[0] = 42
lst[1] = 42
def main3():
lst = [7, 11]
conform3(lst)
print(lst)
Wat wordt geprint voor lst in de functie main3?
Antwoord¶
main3()
[42, 42]
Dictionaries¶
Dictionaries zijn willekeurige containers
d = {47: 2, 42: 1}
Elementen (of waarden) worden opgehaald met een sleutel op een willekeurige positie
d[47] == 2
d[42] == 1
Goed nieuws, sleutels kunnen ook andere typen dan int zijn!

Een bekende structuur¶
woord ⟶ verklaring
naam ⟶ telefoonnummer
afkorting ⟶ betekenis
dier ⟶ jaren Chinese dierenriem

Dictionaries zijn in¶
zodiac_years = {
"rabbit": [1999, 1987, 1975],
"ox": [1997, 1985, 1973],
"dragon": [2000, 1998]
}
De sleutels zijn hier strings en de bijbehorende waarden zijn lists. Dit voorbeeld gaat over de jaren per dier in de Chinese dierenriem, zie het Wikipedia artikel voor alle dieren en jaren!
Is "dragon" een sleutel in zodiac_years?
"dragon" in zodiac_years
True
Is 1969 een waarde in zodiac_years["dragon"]?
1969 in zodiac_years["dragon"]
False
Woorden tellen¶
list_of_words = ["spam", "spam", "taart", "spam"]
word_count = {}
for word in list_of_words:
if word not in word_count:
word_count[word] = 1
else:
word_count[word] += 1
word_count
{'spam': 3, 'taart': 1}
Model genereren¶
Gegegeven de volgende text:
text = "Ik wil taarten en 42 en spam. Ik krijg toch spam en taarten voor de vakantie? Ik wil 42 taarten!"
list_of_words = text.split()
word_count = {}
for word in list_of_words:
if word not in word_count:
word_count[word] = 1
else:
word_count[word] += 1
print(f"There are {len(word_count)} DISTINCT words") # expressions in f-strings!
word_count
There are 13 DISTINCT words
{'Ik': 3,
'wil': 2,
'taarten': 2,
'en': 3,
'42': 2,
'spam.': 1,
'krijg': 1,
'toch': 1,
'spam': 1,
'voor': 1,
'de': 1,
'vakantie?': 1,
'taarten!': 1}
Met een paar aanpassingen van het programma dat worden telt, is het mogelijk om een eenvoudige taalgenerator te maken.
In plaats van het tellen van woorden zal worden gekeken welk woord na een voorgaand woord wordt gebruikt.
%run assets/markov.py
words_follow = create_dictionary(text)
words_follow
{'$': ['Ik', 'Ik', 'Ik'],
'Ik': ['wil', 'krijg', 'wil'],
'wil': ['taarten', '42'],
'taarten': ['en', 'voor'],
'en': ['42', 'spam.', 'taarten'],
'42': ['en', 'taarten!'],
'krijg': ['toch'],
'toch': ['spam'],
'spam': ['en'],
'voor': ['de'],
'de': ['vakantie?']}
Het stappenplan voor het maken van een taalmodel is als volgt:
begin met het vorige woord
previous_wordals “$”voor elk volgend woord in de lijst van woorden voeg het toe aan …
maak
previous_wordgelijk aannew_wordbehalve als
new_word[-1]punctuatie is, maakprevious_worddan gelijk aan …
Tekst genereren¶
Een $ staat voor het begin van een zin. Dit model heeft voor elk woord een lijst van woorden waar uit gekozen kan worden. Als we dit random doen, wordt er een random tekst genereerd.
generate_text(words_follow, 42)
'Ik wil taarten en 42 en spam. Ik krijg toch spam en taarten en 42 en 42 en taarten en taarten voor de vakantie? Ik wil 42 en 42 en taarten voor de vakantie? Ik wil 42 taarten! Ik krijg toch spam '
Als we een veel grotere tekst gebruiken om onze database mee te vullen, kunnen we betere teksten generen.
Het stappenplan voor het genereren van tekst is als volgt:
begin met
previous_wordals de “$” stringkies random een
new_worddat volgt opprevious_worden voeg het toe aan …maak
previous_wordgelijk aannew_wordbehalve als
new_word[-1]punctuatie is, maak danprevious_wordgelijk aan …