Listor. TDDD73 Funktionell och imperativ programmering i Python Föreläsning 7. Peter Dalenius Institutionen för datavetenskap 2014-09-23



Relevanta dokument
Lathund, procent med bråk, åk 8

Python. Datatyper. Mer om datatyper. Heltal - 3 Flyttal - 2,456 Listor - [1,2,3,4] Strängar - spam!

Imperativ och Funktionell Programmering i Python #TDDD73. Fredrik Heintz,

Föreläsning 5: Rekursion

Strängar. TDDD64 Programmering i Python Föreläsning 4. Peter Dalenius Institutionen för datavetenskap

Individuellt Mjukvaruutvecklingsprojekt

ANVÄND NAVIGATIONEN I CAPITEX SÄLJSTÖD

Introduktion till programmering D0009E. Föreläsning 9: Tupler och dictionaries

Träning i bevisföring

Tentamen i Programmering grundkurs och Programmering C

Algebra, polynom & andragradsekvationer en pampig rubrik på ett annars relativt obetydligt dokument

Modul 6: Integraler och tillämpningar

Uppdrag: Huset. Fundera på: Vilka delar i ditt hus samverkar för att elen ska fungera?

Axiell Arena. Samarbeta om bilder Regionbiblioteket i Kalmar län

Skriva B gammalt nationellt prov

Idag: Dataabstraktion

Manual för BPSD registret. Version 6 /

Snabbslumpade uppgifter från flera moment.

ELEV- HANDLEDNING (Ansökan via webben)

Webb-bidrag. Sök bidrag på webben Gäller från

Q1 Hur många undervisningstillfällen har du haft under september månad?

Sekvensdatatyper, ASCII och chiffer. Linda Mannila

Idag. Hur vet vi att vår databas är tillräckligt bra?

Vi skall skriva uppsats

Gissa det hemliga talet

Sammanfattning på lättläst svenska

TDDE44 Programmering, grundkurs

Selektion och iteration

Hur skapar man formula r

Ekvationssystem, Matriser och Eliminationsmetoden

DOP-matematik Copyright Tord Persson. Bråktal Läs av vilka tal på tallinjen, som pilarna pekar på. Uppgift nr

ANVÄNDARHANDLEDNING FÖR

Tentamen TEN1 HI

729G04 - Hemuppgift, Diskret matematik

Tränarguide del 1. Mattelek.

DATASAMORDNING NYHETERNA I CHAOS Utbildning Chaos/Handledning - Nyheterna i Chaos 3/

Presentationsövningar

Erfarenheter från ett pilotprojekt med barn i åldrarna 1 5 år och deras lärare

DD1320 Tillämpad datalogi. Lösning (skiss) till tenta 20 okt 2011

David Wessman, Lund, 30 oktober 2014 Statistisk Termodynamik - Kapitel 5. Sammanfattning av Gunnar Ohléns bok Statistisk Termodynamik.

Moment 2 - Digital elektronik. Föreläsning 1 Binära tal och logiska grindar

Efter att du har installerat ExyPlus Office med tillhörande kartpaket börjar du med att göra följande inställningar:

Utveckla arbetsmiljö och verksamhet genom samverkan

Föreläsning 6: Introduktion av listor

Föreläsningsanteckningar, Introduktion till datavetenskap HT S4 Datastrukturer. Tobias Wrigstad

konstanterna a och b så att ekvationssystemet x 2y = 1 2x + ay = b 2 a b

LÄSFÖRSTÅELSE PROVKAPITEL. Katarina Neiman Hedensjö

4-6 Trianglar Namn:..

Skapa en rapport med snygg formatering, rubriker, sidnummer och innehållsförteckning

Administrera utskick på utbildningstillfälle

Administration Excelimport

Två konstiga klockor

Hävarmen. Peter Kock

TDDC74 Programmering, abstraktion och modellering DUGGA 2

VÄRDERINGSÖVNINGAR. Vad är Svenskt?

Lathund till Annonsportalen

Introduktion till programmering SMD180. Föreläsning 9: Tupler

Lite skoj - typ. 5DV085 - Programspråk. Jan Erik Moström, Department of Computing Science, Umeå University - jem@cs.umu.se

Datorövning 2 Statistik med Excel (Office 2007, svenska)

L(9/G)MA10 Kombinatorik och geometri Gruppövning 1

Menys webbaserade kurser manual för kursdeltagare. Utbildningsplattform: Fronter

VoteIT Documentation. Utgåva 0.1. VoteIT and contributors

Boken om Teknik. Boken om Teknik är en grundbok i Teknik för åk 4 6.

Hur man programmerar. TDDC66 Datorsystem och programmering Föreläsning 3. Peter Dalenius Institutionen för datavetenskap

UTMANINGAR OCH MÖJLIGHETER HAR DU 730 DAGAR OCH ETT STARKT DRIV DÅ HAR VI EN LEDARROLL TILL DIG

Grundläggande datalogi - Övning 1

NATIONELLA MATEMATIKTÄVLING

Programmera en NXT Robot

Innehåll. Binära sökträd. Binärt sökträd. AVL-träd. Exempel på ett AVL-träd. ÿdelar av kapitel 15 i boken + OH-bilderna

När jag har arbetat klart med det här området ska jag:

QFD. Quality Function Deployment Boris Mrden Tobias Lindström Arefeh Mirzaie Shra Morin Habib David Bizzozero

Texturbild. Lagerpaletten du kommer arbeta med ser du till höger. 1. Kopiera bakgrunden till ett nytt lager och gör den svartvit.

912 Läsförståelse och matematik behöver man lära sig läsa matematik?

Nämnarens adventskalendern 2007

7. SAMHÄLLSORIENTERING ÅK 5

TIMREDOVISNINGSSYSTEM

SF1620 Matematik och modeller

Möbiustransformationer.

Sammanfatta era aktiviteter och effekten av dem i rutorna under punkt 1 på arbetsbladet.

Gemensam problemlösning. Per Berggren och Maria Lindroth

Kampanj kommer från det franska ordet campagne och innebär att man under en tidsbegränsad period bedriver en viss verksamhet.

Vad är det och hur definierar vi en Biblioteksfunktioner (math) Top-down-programmering lokala globala variabler Arrays som in-parametrar

a n = A2 n + B4 n. { 2 = A + B 6 = 2A + 4B, S(5, 2) = S(4, 1) + 2S(4, 2) = 1 + 2(S(3, 1) + 2S(3, 2)) = 3 + 4(S(2, 1) + 2S(2, 2)) = = 15.

Visualisering av golfboende

Virkade tofflor. Storlek & By: Pratamedrut. pratamedrut.se/blog/virkade tofflor 1

Utbildningsmodulen i IdrottOnline-appen

Anställning timavlönade i Personec

Kapitel 6. f(x) = sin x. Figur 6.1: Funktionen sin x. 1 Oinas-Kukkonen m.fl. Kurs 6 kapitel 1

Guide för att hitta markavvattningssamfälligheter och täckdikningsplaner

Du ska nu skapa ett litet program som skriver ut Hello World.

Manual för Min sida 1/ rev

Laganmälan & Laghantering

Sundbybergs stad Skolundersökning 2015 Föräldrar förskola Stella Nova förskola

3.1 Linjens ekvation med riktningskoefficient. y = kx + l.

FRÅN A TILL Ö LäraMera Ab / och Allemansdata Ab / FRÅN A TILL Ö

Introduktion. Den objektorienterade modellen Grundläggande begrepp Klass Klassen som abstraktion

Mätningar på op-förstärkare. Del 3, växelspänningsförstärkning med balanserad ingång.

ÖSS jolles Seglarsaga

08/11/13. Databasteknik och informationssystem DD1370 F3. Ett urval ur databasen bestäms av en SQL-fråga. Påminnelse: Deadline på tisdag

Transkript:

Listor TDDD73 Funktionell och imperativ programmering i Python Föreläsning 7 Peter Dalenius Institutionen för datavetenskap 2014-09-23

Översikt Ytterligare exempel på dubbelrekursion Inbyggda metoder hos listor Exempel som använder listmetoder Tupler (konstanta listor) Dictionaries Binära sökträd 2

Ytterligare exempel på dubbelrekursion Vi vill ha en funktion remove som kan ta bort alla förekomster av ett element ur en lista. Listan kan innehålla underlistor, och dessa ska också gås igenom. Lösningen ska egentligen bygga upp en ny lista utan det givna elementet, snarare än att fysiskt plocka bort det. Vi tänker oss i första hand en rekursiv lösning och gör följande fallanalys. Hur kan man tänka sig att olika listor börjar och hur ska vi behandla dem? Tom lista Första elementet är en underlista Första elementet är det vi ska ta bort Första elementet är något annat Tom lista Bearbeta både underlistan och resten Fortsätt med resten Bygg ihop och fortsätt med resten 3

Rekursiv lösning def remove(seq, x): if not seq: return [] elif isinstance(seq[0], list): # return [remove(seq[0], x)] + remove(seq[1:], x) # elif seq[0] == x: return remove(seq[1:], x) else: return [seq[0]] + remove(seq[1:], x) 4

Iterativ lösning def remove(seq, x): result = [] for elem in seq: if elem isinstance(elem,!= x: list): # result += [elem] [remove(elem, x)] # elif elem!= x: result += [elem] return result Det är svårt att få till en helt igenom iterativ lösning som klarar av godtyckligt djupa strukturer. 5

Listmetoder >>> s = [4711, 17, 496] >>> s.append(42) >>> s [4711, 17, 496, 42] >>> s.index(17) 1 >>> s.insert(1, 17) >>> s [4711, 17, 17, 496, 42] >>> s.count(17) 2 >>> s.remove(17) >>> s [4711, 17, 496, 42] >>> s.reverse() >>> s [42, 496, 17, 4711] >>> s.sort() >>> s [17, 42, 496, 4711] >>> s.pop() 4711 >>> s [17, 42, 496] >>> s.pop(1) 42 >>> s [17, 496] 6

Listmetodernas felhantering >>> list = [1, 2, 3, 4] >>> list.remove(42) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: list.remove(x): x not in list >>> list.pop(42) Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: pop index out of range >>> list.insert(42, 42) >>> list [1, 2, 3, 4, 42] 7

Ta bort element ur en lista >>> list = ['one', 2, 3, 4, 5, 6] >>> del list[0] >>> list [2, 3, 4, 5, 6] >>> del list[1:3] >>> list [2, 5, 6] 8

Exempel Vi vill ha en funktion remove som tar bort alla förekomster av ett element ur en rak lista, d.v.s. vi struntar i eventuella underlistor. Funktionen ska vara destruktiv, d.v.s. den ska inte bygga upp en ny lista som resultat, utan ska verkligen plocka bort de element vi inte vill ha med med hjälp av någon av metoderna remove() eller pop(). >>> list = [1, 2, 3, 4, 2, 5] >>> remove(list, 2) >>> list [1, 3, 4, 5] Vi ska titta på flera olika sätt att lösa problemet. 9

Lösning 1 Räkna hur många gånger elementet förekommer och anropa sedan remove() så många gånger. def remove(seq, x): for i in range(seq.count(x)): seq.remove(x) Fördelar: Lite kod att skriva. Använder inbyggda metoder. Nackdelar: Kommer att gå igenom listan flera gånger. 10

Lösning 2 Gå igenom listan element för element. Anropa pop() för varje element som matchar. Nackdelar: Fungerar inte! Eftersom vi tar bort element kommer listan att vara för kort när loopen kommer till vad den tror är slutet. def remove(seq, x): for i in range(len(seq)): if seq[i] == x: seq.pop(i) 11

Lösning 3 Gå igenom listan element för element, baklänges. Anropa pop() för varje element som matchar. Fördelar: Fungerar. Eftersom vi räknar baklänges kommer elementen försvinna från den del av listan vi är klara med. def remove(seq, x): for i in range(len(seq)-1,-1,-1): if seq[i] == x: seq.pop(i) Nackdelar: Lite bökigt att räkna baklänges (även om man fixar det i anropet till range). 12

Lösning 4 Gå igenom listan element för element, men kolla mot längden på listan varje varv. Anropa pop() för varje element som matchar. Fördelar: Kan upplevas som mer lättläst än de övriga lösningarna, eftersom den är mer rakt på. Nackdelar: Vi måste beräkna längden av listan en gång varje varv. Vi måste själva initiera och uppdatera i. def remove(seq, x): i = 0 while i < len(seq): if seq[i] == x: seq.pop(i) else: i += 1 Ny konstruktion while som också kan användas för upprepningar. 13

Tupler En tupel är en konstant lista. När den väl är skapad är den oföränderlig. Tupler ser ut som och funkar som listor, men begränsas av vanliga parenteser istället för hakparenteser. >>> tp = (1, 2, 3) >>> tp[1] 2 >>> len(tp) 3 >>> for elem in tp: print(elem, end="*")... 1*2*3 14

Tupler >>> tp[1] = 'hello' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> tp.append(42) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'tuple' object has no attribute 'append' >>> tp2 = 'a', 'b', 'c' >>> tp2 ('a', 'b', 'c') >>> 1, (1,) 15

Tupler Även om tupler i sig är oföränderliga (eng. immutable) så kan vi skapa nya tupler utifrån gamla. En tupel kan också innehålla data som i sig går att förändra. >>> (1, 2) + (3, 4) (1, 2, 3, 4) >>> struktur = (['a', 42], ['b', 37]) >>> struktur[0][1] = 4711 >>> struktur (['a', 4711], ['b', 37]) 16

Tupel eller lista? Eftersom tupler aldrig kan ändras och alltså alltid har samma storlek och innehåll, så kan de interna rutinerna göras snabbare. Tupler är alltså mer effektiva och lämpar sig för tillfällen när man har konstana sekvenser, t.ex. months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', \ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') En användbar konvention är att använda tupler när man har strukturerade data där informationen på olika positioner har olika roller, och listor när man har sekvenser av likadana data. date = (2012, 9, 11) dates = [(2012, 8, 27), (2012, 8, 29), (2012, 9, 3)] 17

Dictionaries Dictionaries (eller dictar) är listor av par som man kan använda som uppslagningstabeller. Varje par består av en nyckel och ett värde. Genom att ange nyckeln kan man slå upp värdet. I övrigt funkar de ungefär som vanliga listor. >>> dict = {'a': 45, 'b': 39, 'c': 19} >>> dict['a'] 45 >>> dict['d'] = 4711 >>> dict {'a': 45, 'c': 19, 'b': 39, 'd': 4711} >>> len(dict) 4 18

Dictionaries >>> 'b' in dict True >>> 'q' in dict False >>> dict['q'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'q' >>> for elem in dict: print(elem, end="*")... a*b*c*d* 19

Dictionaries Nycklarna kan vara vilka värden som helst som är oföränderliga (eng. immutable). Samma nyckel kan inte förekomma två gånger. Ordningen mellan paren så som de visas om vi tittar på dicten är egentligen ointressant och Python lämnar inga garantier för i vilken ordning de lagras. >>> {1: 4, 'a': 47, (1, 2): 'hejsan'} {'a': 47, 1: 4, (1, 2): 'hejsan'} En mer allmän benämning på den här typen av datastruktur är hashtabell. Grundtanken är att det finns en algoritm som för varje nyckel beräknar ett hashvärde som används som internt index för att snabbt kunna slå upp det värde vi letar efter. 20

Sammansatta datatyper Datatyp Innehåll? Muterbar? Indexering? str Text Nej Heltal list Vad som helst Ja Heltal tuple Vad som helst Nej Heltal dict Vad som helst Ja Nästan vad som helst 21

Binära sökträd (BST) Träd Gren/Subträd Nod 8 Inre nod Löv 3 10 Nyckel Rot 1 6 14 Barn Nivå 4 7 13 Djup Tomt träd 22

Binära sökträd (BST) Binärt, d.v.s. varje nod har maximalt två grenar under sig. Ordnade så att nyckeln i en viss nod är större än alla nycklar i vänstra grenen, och mindre än eller lika med alla nycklar i högra grenen. Ofta lagras mer än enbart nyckeln i noden. Ett sätt att organisera datamängder för att lätt kunna söka reda på information (om man känner till nyckeln). 1 6 8 3 10 14 4 7 13 23

Rekursiv sökning i ett binärt sökträd Finns x i trädet t? Om t är ett tomt träd finns inte x i det. Om t är ett löv kollar vi om t = x. Om x < nyckeln i roten av t, fortsätt söka i vänster gren. Om x > nyckeln i roten av t, fortsätt söka i höger gren. Annars har vi en träff! 8 3 10 1 6 14 4 7 13 24

Hur får vi in dem i Python? Det finns inga inbyggda binära sökträd i Python. De är en abstrakt datatyp (ADT). Om vi vill kunna arbeta med binära sökträd måste vi implementera dem själva, d.v.s. skriva funktioner som kan göra allt det vi vill göra med binära sökträd. För att kunna göra det måste vi bestämma ett sätt att representera binära sökträd med hjälp någon av de inbyggda datatyperna i Python. 25

Representation av binära sökträd Det tomma trädet representeras av en tom lista [ ]. Löv representeras av heltal. Inre noder representeras som en lista på formen [vänster gren, nyckel, höger gren]. Detta är endast ett bland många möjliga sätt att representera binära sökträd i Python. 26

Exempel på representation 8 3 10 1 6 14 4 7 13 [[1, 3, [4, 6, 7] ], 8, [[], 10, [13, 14, []]]] 27

Primitiva funktioner De primitiva funktionerna hjälper oss att implementera representationen. De är var för sig ganska enkla, men fungerar som ett gränssnitt gentemot andra funktioner som vill arbeta med binära sökträd. def är_tomt_träd(träd): return isinstance(träd, list) and not träd def är_löv(träd): return isinstance(träd, int) def skapa_träd(vänster_träd, nyckel, höger_träd): return [vänster_träd, nyckel, höger_träd] def vänster_subträd(träd): return träd[0] def höger_subträd(träd): return träd[2] 28

Rekursiv sökning i ett binärt sökträd Finns x finns i trädet t? Om t är ett tomt träd finns inte x i det. Om t är ett löv kollar vi om t = x. Om x < nyckeln i roten av t, fortsätt söka i vänster gren. Om x > nyckeln i roten av t, fortsätt söka i höger gren. Annars har vi en träff! def sök(träd, x): if är_tomt_träd(träd): return False elif är_löv(träd): return träd == x elif x < nyckel(träd): return sök(vänster_subträd(träd), x) elif x > nyckel(träd): return sök(höger_subträd(träd), x) else: return True Funktionen nyckel plockar fram nyckeln ur roten av ett träd. Funktionen sök känner inte till representationen, utan arbetar enbart med de primitiva funktionerna. 29

Exempel på sökning def sök(träd, x): if är_tomt_träd(träd): return False 8 elif är_löv(träd): return träd == x 3 10 elif x < nyckel(träd): return sök(vänster_subträd(träd), x) 1 6 14 elif x > nyckel(träd): return sök(höger_subträd(träd), x) else: 4 7 13 return True 30

www.liu.se