Strängar TDDD64 Programmering i Python Föreläsning 4 Peter Dalenius Institutionen för datavetenskap 2014-09-12
Översikt Grundläggande operationer på strängar Exempel på funktioner som arbetar med strängar Inbyggda metoder hos strängar Utskrifter Teckenkodning Dubbelrekursion över listor Fallanalys 2
>>> 'Spam and eggs' 'Spam and eggs' >>> "Spam and eggs" 'Spam and eggs' >>>'I want to "quote" something' 'I want to "quote" something' >>> 'We have double " and single \'' 'We have double " and single \'' >>> s = 'Spam\nEggs' >>> s 'Spam\nEggs' >>> print(s) Spam Eggs >>> 'spam' + 'eggs' 'spameggs' >>> 'spam' * 4 'spamspamspamspam' Strängar Strängar är sekvenser av tecken som innesluts av enkla eller dubbla citationstecken. Strängar kan innehålla specialtecken som markeras med bakåtsnedstreck \. 3
Indexering av strängar >>> s = "Spamalot >>> s[1] 'p' >>> s[-2] 'o' >>> len(s) 8 >>> s[len(s)-1] 't' >>> type(s[0]) <class 'str'> S p a m a l o t 0 1 2 3 4 5 6 7-8 -7-6 -5-4 -3-2 -1 4
Slicing (ta ut delsträngar) >>> s = 'Spamalot' >>> s[1:] 'pamalot' >>> s[1:3] 'pa' >>> s[:5] 'Spama' >>> s[:-1] 'Spamalo' >>> s[:] 'Spamalot' S p a m a l o t 0 1 2 3 4 5 6 7 8-8 -7-6 -5-4 -3-2 -1 5
Strängar som konstanta sekvenser >>> s = 'Spamalot' >>> s[1] = 'q' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object does not support item assignment >>> for c in s:... print(c, end="*")... S*p*a*m*a*l*o*t* 6
Jämförelser med strängar >>> "Aardvark" < "Abbot" True >>> "Queen" > "King" True >>> "a" * 4 == "aaaa" True >>> "a" in "The Holy Grail" True >>> "vers" in "universitet" True 7
Vad kan vi göra med strängar (hittills)? Operation s + s s * 4 s[3] s[1:3] len(s) for c in s:... Vad händer? Konkatenering(sammanslagning) Upprepning Indexering Slicing (ta ut delsträngar) Längden av strängen Iterera genom teckneni strängen Se sidan 125 i läroboken! Alla dessa operationer fungerar precis lika bra på listor också! 8
Exempel 1: Byta ut ett tecken Vi vill ha en funktion change som tar en sträng och byter ut alla förekomster av ett visst tecken mot ett annat (genom att skapa en ny sträng, givetvis). >>> change("gurkburk","u","ö") 'görkbörk' >>> change("gräset växer","ä","e") 'greset vexer' 9
Exempel 1: Byta ut ett tecken Spamalot S p a m a l o t nej nej ja nej ja nej nej nej S p * m * l o t Sp*m*lot 10
Exempel 1: Byta ut ett tecken def change(string,original,new): result = "" for char in string: if char == original: result = result + new else: result = result + char return result >>> change("gurkburk","u","ö") 'görkbörk' >>> change("gräset växer","ä","e") 'greset vexer >>> change("rödrutig regnrock","r","ow") 'owödowutig owegnowock' 11
Exempel 2: Hitta en delsträng Vi vill ha en funktion locate som kan kolla om en delsträng finns någonstans i en längre sträng. Om så är fallet returneras index för den position där delsträngen finns, annars returneras -1. >>> locate("spam and eggs","egg") 9 >>> locate("team","i") -1 12
Exempel 2: Hitta en delsträng 0 1 2 3 4 5 6 7 S p a m a l o t långa strängens längd s = 8 0:3 1:4 2:5 3:6 4:7 5:8 slice av långa strängen att jämföra med m a l m a l m a l m a l m a l m a l korta strängens längd p = 3 antal varv = s - p + 1 = 6 13
Exempel 2: Hitta en delsträng def locate(string,part): s = len(string) p = len(part) for i in range(s-p+1): if string[i:i+p] == part: return i return -1 >>> locate("spam and eggs","egg") 9 >>> locate("team","i") -1 14
Strängmetoder >>> s = 'Spam and eggs' >>> s.find('am') 2 >>> s.count('a') 2 >>> s.replace('a','qwerty') 'SpQWERTYm QWERTYnd eggs' >>> s.split(' ') ['Spam', 'and', 'eggs'] >>> 'Spam\n'.rstrip() 'Spam' >>> s.upper() 'SPAM AND EGGS' >>> s.title() 'Spam And Eggs' 15
Funktioner eller metoder? All information som en funktion behöver för att utföra sitt uppdrag kommer genom argumenten. >>> len("korvbröd") 8 Metoder är specialiserade funktioner som hör till en viss datatyp. Man kan inte köra dem utan att ha ett objekt av den typen. Mallen är dataobjekt.metod(parametrar). >>> "Korvbröd".upper() 'KORVBRÖD' Vi kommer inte att lära oss att göra egna metoder i den här kursen, men vi kan använda de inbyggda metoderna för strängar m.fl. dataobjekt. 16
Hjälp om metoder och funktioner >>> dir("") ['capitalize', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha',...] >>> help("".replace) Help on built-in function replace: replace(...) S.replace(old, new[, count]) -> str Return a copy of S with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. Se tabell över strängmetoder på sidan 140 i läroboken! 17
>>> Utskrifter print('that is', 1, 'dead bird!') That is 1 dead bird! >>> print('that is', 1, 'dead bird!',end='stop') Skriv ut tre saker separerade med mellanslag och avsluta med ny rad. That is 1 dead bird!stop>>> print(1,2,3,sep='spam') 1SPAM2SPAM3 >>> print(1,2,3,sep=' ',end='\n') 1 2 3 >>> 'That is ' + str(1) + ' dead bird!' 'That is 1 dead bird!' >>> int('4711') 4711 18
Formatterad utskrift Om man har många olika saker att skriva ut kan man använda formatterad utskrift med metoden format så här: mallsträng.format(parametrar) >>> "A {0} {1} is a {1} that's {0}.".format('hot','dog') "A hot dog is a dog that's hot." >>> 'Use the {}, {}!'.format('power','amy') 'Use the power, Amy!' Observera att format returnerar en sträng. Den skriver inte ut något. 19
Fler anpassningar >>> '{0:>10}'.format('spam') De objekt som ska skrivas ut ' spam' kan anpassas ytterligare med >>> '{:<10}'.format('spam') olika koder. 'spam ' >>> '{:^10}'.format('spam') ' spam ' >>> '{:e}'.format(3.14) '3.140000e+00' >>> '{:f}'.format(3.14) '3.140000' >>> '{:.2f}'.format(3.14) '3.14' >>> '{:7.2f}'.format(3.14) ' 3.14' >>> '{:07.2f}'.format(3.14) '0003.14' Här ser vi exempel på justering av strängar och formattering av flyttal. Det finns många fler alternativ. 20
Hur lagras strängar? >>> ord('a') 97 >>> chr(87) 'W'... 97 a 98 b P y t h o n 80 121 116 104 111 110 0 1 2 3 4 5 99 c 100 d 101 e... Python 21
Olika teckenkodningar ASCII (American Standard Code for Information Interchange) från 1963 är en teckenkodning som tilldelar talen 0-127 olika tecken, men som saknar t.ex. svenska bokstäver. ISO 8859-1 (även kallad Latin-1) är en utökning som tilldelar talen 0-255 olika tecken och som inkluderar svenska och många andra europeiska tecken. Unicode är den mest aktuella världsstandarden med målet att inkludera alla världens skrivtecken. 22
Problem med olika teckenkodningar Python använder normalt Unicode, men IDA:s datorsystem använder fortfarande Latin-1. Så länge man undviker bl.a. svenska tecken är detta inget problem För att ställa om Pythons teckenkodning, placera följande kommentar först i varje Python-fil: # encoding: iso-8859-1 23
Dubbelrekursion över listor Vi har tidigare skrivit funktioner som med hjälp av iteration eller rekursion bearbetat alla element i en sträng eller en lista. Listor är mer generella än strängar och kan innehålla i princip vad som helst, t.ex. andra listor. Om vi vill behandla alla element i den typen av mer komplicerade strukturer är det i princip enbart rekursion som gäller, om man ska lösa det generellt. Vi kallar det för dubbelrekursion när vi bearebetar listor i listor. >>> s1 = [1, 'two', 3, 4] >>> s2 = [1, 'two', [3, 4, 'five'], [True]] >>> len(s2) 4 >>> type(s2[2]) <class 'list'> 24
Dubbelrekursion 1 two True def len2(seq): if not seq: return 0 elif isinstance(seq[0], list): return len2(seq[0]) + len2(seq[1:]) else: return 1 + len2(seq[1:]) 3 4 five Hur beräknar man den totala längden när man har listor i listor? s2 = [1, 'two', [3, 4, 'five'], [True]] 25
a: len2([1, 'two', [3, 4, 'five'], [True]]) b: len2(['two', [3, 4, 'five'], [True]]) c: len2([[3, 4, 'five'], [True]]) d: len2([3, 4, 'five']) e: len2([4, 'five']) f: len2(['five']) g: len2([]) g: 0 f: 1 e: 2 d: 3 d: len2([[true]]) e: len2([true]) f: len2([]) f: 0 e: 1 d: 1 c: 4 b: 5 a: 6 def len2(seq): if not seq: return 0 Spårning: Vad händer? elif isinstance(seq[0], list): return len2(seq[0]) + len2(seq[1:]) else: return 1 + len2(seq[1:]) 26
Fallanalys Betrakta mängden av alla möjliga indata till funktionen och gruppera efter lämplig åtgärd. En tom lista ger 0 som resultat. [] [1, 2, 3] [ a, [ b ]] 47 3.14 hejsan [[ q, w ], e ] Data som inte är listor ignorerar vi. Listor som börjar med en enkel datatyp har längden 1 + längden av resten. [[13, 19, 17], [4, 5]] Listor som börjar med en underlista har längden av underlistan + längden av resten. 27
Felaktiga antaganden om personnamn Varje person har exakt ett kanoniskt fullständigt namn. Varje person har exakt ett kanoniskt fullständigt namn som de faktiskt använder. För en given tidpunkt har varje person exakt ett kanoniskt fullständigt namn som de faktiskt använder. Varje person har exakt N namn, för något värde på N. Alla tänkbara namn får plats i en sträng om N tecken. En persons namn ändras aldrig. En persons namn ändras, men enbart vid särskilda tillfällen (som definieras enligt en oföränderlig och kort lista). Personer får namn i samband med att de föds. Förnamn och efternamn är alltid olika. Varje person har ett förnamn och ett efternamn. 28 Källa: http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/
Felaktiga antaganden om personnamn Varje person har åtminstone ett namn som är gemensamt med andra personer i samma familj eller släkt. Namn är globalt unika. Namn är nästan unika. Det kan åtminstone inte finnas mer än en handfull personer som har samma namn, i hela världen. Alla namn kan skrivas med ASCII-tecken. Alla namn kan skrivas med Unicode-tecken. Namn är skiftlägeskänsliga (eng. case sensitive). Mitt system kommer aldrig att behöva behandla namn från Kina. Eller Ryssland. Eller Botswana. Två olika system som innehåller information om samma person kommer att använda exakt samma namn för att benämna personen ifråga. 29 Källa: http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/
30 Källa: http://xkcd.com/974/ Det generella problemet
www.liu.se