TDDE44 Programmering, grundkurs Föreläsning 5 Jody Foo, jody.foo@liu.se
Föreläsning 5 & 6 Laboration 3: En egen pokedex data från webben Ny datatyp: dictionary Mer om dataabstraktion Nästlade datastrukturer Bearbetning av nästlade datastrukturer Rekursion
Korrigering från förra föreläsningen Fel: Alla värden förrutom 0, False och None är sanna Rätt: Alla värden förrutom 0, False, None, tomma sekvenser och tomma dictionarys är sanna.
Laboration 3 Del 1: Pythonuppgifter 3 Del 2: Egen Pokedex; hämta information från webben
Kort om laboration 3, del 2 Hämta information från webben istället för från fil Nytt textbaserat data-format: JSON Webb-API:er - om URL:er vore funktioner PokeAPI - ett webb-api till en databas om Pokémon pokedex.py - skript som skriver ut information om en pokémon.
Ny datatyp: dictionary
Dictionaries Ett dictionary har element precis som en lista, men istället för index, kommer man åt elementen med via nycklar. Varje nyckel är associerat med ett värde. Alla datatyper som är oföränderliga (immutable) kan användas som nycklar, t.ex. flyttal, heltal, strängar, tupler Till skillnad från en lista, finns det ingen bestämd ordning på nyckel-värde-paren i ett dictionary.
Dictionaries - en mängd nyckelvärde-par # Ett dictionary omges av {} och består av nycklar och värden: # { nyckel_1:värde1, # nyckel_2:värde2, #..., # nyckel_n:värde_n } # Exempel dictionary1 = {"nyckel1":"värde 1", 345:"värde 2", 3:54 } Ett dictionary används för att lagra värden med associativ åtkomst, dvs att en nyckel kan användas för att komma åt ett värde. Som en lista, men med nycklar istället för index. Som nyckel kan alla oföränderliga (immutable) datatyper användas. Alla datatyper kan vara värden.
Istället för index använder vi nyckeln In [1]: dictionary1 = {"nyckel1":"värde 1", 345:"värde 2", 3:54 } In [2]: dictionary1["nyckel1"] Out[2]: 'värde 1' In [3]: dictionary1[345] Out[3]: 'värde 2' In [4]: dictionary1[3] Out[4]: 54 In [5]: Jämfört med en lista så använder vi nyckeln istället för index för att "komma åt" värdena.
Vi kan ändra värden genom att använda nyckeln In [5]: dictionary1 = {"nyckel1":"värde 1", 345:"värde 2", (3):54 } In [6]: dictionary1["nyckel1"] Out[6]: 'värde 1' In [7]: dictionary1["nyckel1"] = 1024 In [8]: dictionary1["nyckel1"] Out[8]: 1024 Precis som att man kan ange ett index vid tilldelning av ett värde på ett element i en lista, så kan man ange en nyckel vid tilldelning av ett associerat värde i en dictionary.
Vi kan lägga till element till ett dictionary In [9]: dictionary1 = {"nyckel1":"värde 1", 345:"värde 2", (3):54 } In [10]: dictionary1["ny nyckel"] = "nytt värde" In [11]: dictionary1["böcker"] = ["bok 1", "bok 2", "bok 3"] In [12]: dictionary1["ny nyckel"] Out[12]: 'nytt värde' In [13]: dictionary1["böcker"] Out[13]: ['bok 1', 'bok 2', 'bok 3'] Till skillnad från att använda index som är större än längden på listan, så kan man lägga till nya värden i ett dictionary genom att använda en ny nyckel.
Ny operator: in Operatorn in kan användas på sekvenser (listor och strängar) samt dictionaries. Returnerar True om den hittar det sökta elementet i sekvensen/ bland dictionaryts nycklar. OBS! Inte samma som det in som används i samband med en forloop "a" in "Python är ett programmeringsspråk" True 4 in [1, 2, 3, 4] True 4 in [1, 2, 3, [4]] False "hej" in { "ja": "yes", "nej": "no", "hej": "hello" } True
Vad kan användas som en nyckel? OK att använda som nycklar: siffror, strängar Inte OK att använda som nycklar: listor, dictionaries Varför kommer vi prata om lite längre fram i kursen.
Loopa igenom ett dictionary
Alla nycklar/värden/nyckelvärdepar för ett dictionary Punktnotation för att komma åt alla nycklar: dict.keys() värden: dict.values() nyckel-värdepar: dict.items() "dict" refererar till ett värde av typen dictionary, denna notation används även i pythondokumentationen Funktioner som anropas via punktnotation kallas för metoder. Metoderna dict.keys(), dict.values() och dict.items() returnerar en "vy" in i dictionary-värdet.
Vi kan loopa genom nycklar i ett dictionary # loopa genom nycklar, explicit (ingen _bestämd_ ordning finns) for key in dictionary1.keys(): print("key: " + key) print("value: " + dictionary1[key]) # loopa genom nycklar, implicit (ingen _bestämd_ ordning finns) for key in dictionary1: print("key: " + key) print("value: " + dictionary1[key]) Vi kan komma åt alla nycklar antingen implicit eller explicit. Operatorn in kan också användas på nycklarna implicit: if key_i_am_looking_for in dictionary1
Vi kan loopa genom värden i ett dictionary # loopa genom värden, explicit (ingen _bestämd_ ordning finns) for value in dictionary1.values(): print("value: " + value) dict.values(), precis som dict.keys() ger en struktur (ett view objekt) som beter sig som en lista (men det är ingen riktig lista). Se https://docs.python.org/release/3.3.0/library/stdtypes.html#dict-views för mer information.
Dataabstraktion Strukturera information
Abstraktion programabstraktion: dela upp problem i delproblem, dela upp en funktion i flera funktioner dataabstraktion: koppla ihop och strukturera information
Dataabstraktion # en variabel per värde pokemon_name = "pidgey" ability1 = "big-pecks" ability2 = "tangled-feet" ability3 = "keen-eye" Hur gör vi om vi vill ha information om fler eller färre "abilities" på ett smidigt sätt?
Dataabstraktion pokemon_name = "pidgey" # listor kan användas för att lagra 0 eller fler värden abilities = ["big-pecks", "tangled-feet", "keen-eye"] Listor kan användas för information som kan fler än ett värde. Hur gör vi om vi vill ha information om flera pokemons? Ska vi ha pokemon_name1, pokemon_name2, abilities1, abilities2?
Dataabstraktion pokemon1 = ["pidgey", ["big-pecks", "tangled-feet", "keen-eye"]] pokemon2 = ["ditto", ["imposter", "limber"]] Vi kan samla ihop informationen om varje pokemon till en lista samt bestämma den ordning som informationen ska komma i.
Dataabstraktion pokemon = [ ["pidgey", ["big-pecks", "tangled-feet", "keen-eye"]], ["ditto", ["imposter", "limber"]] ] Vi kan sedan samla ihop alla enskilda pokemons till ytterligare en lista!
Dataabstraktion pokemon = [ { "name": "pidgey", "abilities": ["big-pecks", "tangled-feet", "keen-eye"] }, { "name": "ditto", "abilities": ["imposter", "limber"] } ] Vi hade även kunnat använda ett dictionary för att representera en Pokémon.
Abstrakta datatyper (ADT) Barbara Liskov, Stephen Zilles. 1974. "Programming with abstract data types" Abstrakt datatyp datastruktur funktioner som används på dessa datastrukturer Föregångare till en objektorienterad approach.
Exempel på abstrakt datatyp Kö lista med element är kön, index 0 är nästa på tur funktionen create_empty_queue() som returnerar en tom kö funktionen enqueue(value, queue) som lägger till värdet value till slutet på kön queue funktionen dequeue(queue) som returnerar nästa värde i kön och plockar även bort det från kön
Bearbetning av nästlade datastrukturer
Nästlade datastrukturer A är en nästlad datastruktur om A innehåller flera värden Ett av värdena i A i sin tur innehåller flera värden Exempel: [["Ada Lovelace", 1815], ["Joan Clarke", 1917]] [ { "name": "Ada Lovelace", "birthyear": 1815 }, { "name": "Joan Clarke", "birthyear": 1815 } ] { "name": "ditto", "abilities": ["imposter", "limber"] }
Hur kommer vi åt nästlade värden? lista1 = [["a", "b", "c"], ["d", "e", "f"]] # första elementet i lista1 lista1[0] # första elementet i första elementet i lista1 lista1[0][0] # andra elementet i första elementet i lista1 lista1[0][1]
Hur kommer vi åt nästlade värden? dict1 = { "frukter": ["a", "b", "c"], "bilar": ["d", "e", "f"] } # värdet associerat med nyckeln "frukter" dict1["frukter"] # första elementet i listan associerad med nyckeln "frukter" dict1["frukter"][0] # andra elementet i listan associerad med nyckeln "frukter" dict1["frukter"][1]
En nästlad loop för att bearbeta en nästlad datastruktur yttre_lista = [ ["a", "b", "c"], ["d", "e", "f", "g"] ] # skriv ut varje element i listan yttre_lista index1 = 0 while index1 < len(yttre_lista): print(yttre_lista[index1]) index1 += 1 # om vi för varje inre lista i yttre_lista vill skriva ut den # inre listans element? index1 = 0 while index1 < len(yttre_lista): inre_lista = yttre_lista[index1] # kod som skriver ut varje element i inre_lista
En nästlad loop för att bearbeta en nästlad datastruktur yttre_lista = [ ["a", "b", "c"], ["d", "e", "f", "g"] ] # skriv ut varje element i listan yttre_lista index1 = 0 while index1 < len(yttre_lista): print(yttre_lista[index1]) index1 += 1 # om vi för varje inre lista i yttre_lista vill skriva ut den # inre listans element? index1 = 0 while index1 < len(yttre_lista): inre_lista = yttre_lista[index1] # kod som skriver ut varje element i inre_lista index2 = 0 while index2 < len(inre_lista): print(inre_lista[index2]) index2 += 1 index1 += 1
En nästlad loop för att bearbeta en nästlad datastruktur yttre_lista = [ ["a", "b", "c"], ["d", "e", "f", "g"] ] # skriv ut varje element i listan yttre_lista for yttre_element in yttre_lista: print(yttre_element) # om vi för varje inre lista i yttre_lista vill skriva ut den # inre listans element? for yttre_element in yttre_lista: for inre_element in yttre_element: print(inre_element)