L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E En sammansatt datatyp En sträng är • ett enhetligt värde, som kan lagras i variabler och fungera som operand eller funktionsargument • en datastruktur bestående av enskilda tecken, som i sig är värden Introduktion till programmering D0009E Föreläsning 7: “Strängar” Vilket synsätt som är lämpligast beror på sammanhanget Att plocka ut ett enskilt tecken ur en sträng: >>> fruit = "orange" >>> letter = fruit[1] >>> print letter r 1 2 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K Indexering INTRODUKTION TILL PROGRAMMERING D0009E Indexering Operationen stränguttryck[heltalsuttryck] kallas indexering, där heltalsuttrycket är ett index Att plocka ut det sista tecknet i en sträng: >>> length = len(fruit) >>> last = fruit[length-1] >>> print last e Det första tecknet i en sträng har index 0 – minnesregel: hur gammal är en människa under sitt första levnadsår? >>> fruit = "orange" >>> print fruit[0] o Bekvämt alternativ: >>> last = fruit[-1] Vanligt misstag: >>> length = len(fruit) >>> last = fruit[length] IndexError: string index out of range Den inbyggda funktionen len ger längden av en sträng: >>> len(fruit) 6 3 4 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K Om index Om index Det är lämpligt att tänka sig att index pekar mellan de enskilda tecknen i en sträng: o r a n INTRODUKTION TILL PROGRAMMERING D0009E g ...eller så betraktar man det hela såhär: e index: 0 1 2 3 4 5 -6 -5 -4 -3 -2 -1 o 6 r a n g e index: 0 1 2 3 4 5 -6 -5 -4 -3 -2 -1 Jämför: ... År man fyller: 0 5 1 2 3 4 5 6 6 1 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K Strängsegment INTRODUKTION TILL PROGRAMMERING D0009E Mer om index Delsegment av en sträng (slices) pekas ut av två index: >>> fruit = "orange" >>> print fruit[0:2] or >>> print fruit[3:6] nge Underförstådda index: >>> print fruit[:2] or >>> print fruit[3:] nge >>> print fruit[:] orange 7 Vad är egentligen ett tecken för sorts värde? Svar: ett tecken är en sträng av längden 1! (Python skiljer sig här från de flesta andra språk, som har olika typer för tecken och strängar) Enkel indexering kan därmed ses som en förkortning: sträng[index] betyder delsträngen sträng[index:index+1] Dock med ett viktigt undantag: >>> len(fruit[6:7]) 0 >>> len(fruit[6]) IndexError: string index out of range 8 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K Strängtraversering Skriv ut varje tecken på en rad för sig: index = 0 while index < len(fruit): letter = fruit[index] print letter index = index+1 Att på detta sätt stega igenom varje tecken i en sträng kan uttryckas mer kompakt med hjälp av for-snurran: for letter in fruit: print letter INTRODUKTION TILL PROGRAMMERING D0009E Ett for-exempel till Genererar namn lämpliga för ankor: prefixes = "JKLMNOPQ" suffix = "ack" for letter in prefixes: print letter + suffix, Output: Jack Kack Lack Mack Nack Oack Pack Qack Denna nya sats kan också användas till annat än strängar 9 10 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K Strängjämförelse Likhet: if word == "banana": print "Yes, we have no bananas!" Olikhet (alfabetisk ordning): if word < "banana": print "Your word,", word, "comes before banana." elif word > "banana": print "Your word,", word, "comes after banana." else: print "Yes, we have no bananas!" OBS: alfabetisk ordning betyder egentligen ASCIIordning 11 INTRODUKTION TILL PROGRAMMERING D0009E ASCII Förkortning av American Standard Code for Information Interchange Tabell ("alfabet") innehållande alla tecken på en amerikansk skrivmaskin och deras bitmönster-kodning: • Siffror 0-9 • Bokstäver A-Z samt a-z • Symbolerna !"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~ • Styrtecken typ nyrad, tabulator, form feed, bell, ... Finns i diverse plattformsberoende utvidgningar (åäö...) samt den komplexa Unicode Transformation Format (UTF) 12 2 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K ASCII-tabellen 0 1 2 3 4 5 6 0 7 8 9 INTRODUKTION TILL PROGRAMMERING D0009E Ascii-tabell (en till) 12 13 \a \b \t \n \v \f 10 11 \r 14 15 / 1 ! " # $ % & ' ( ) * + , - . 3 0 1 2 3 4 5 6 7 8 9 : ; < = < ? 4 @ A B C D E F G H I J K L M N O 5 P Q R S T U V W X Y Z [ \ ] ^ _ 6 ` a b c d e f g h i j k l m n o 7 p q r s t u v w x y z { | } ~ 2 platsnummer = rad*16+kolumn 13 14 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K ASCII-tabellen Strängar och tilldelning Naturligtvis lär sig ingen vettig människa hela tabellen utantill... Istället använder man inbygda funktioner (i den mån man alls behöver bry sig om ASCII-värden): • ord(ch) ger platsnumret i tabellen för tecknet ch • chr(n) ger tecknet på plats n i tabellen Viktigt att minnas: • operatorn < på strängar jämför endast tecknens plats i tabellen. Exempel: '*' < '?' och 'Z' < 'a' är båda uttryck som evaluerar till True, av den enkla anledningen att ord('*) < ord('?') och ord('Z') < ord('a') 15 Vi känner redan till effekten av multipel tilldelning: >>> greeting = "Hello, world!" >>> greeting = "Jello, world!" >>> print greeting Jello, world! Är följande kod ett möjligt alternativ? >>> greeting = "Hello, world!" >>> greeting[0] = 'J' Svar: Nej! Strängar är icke muterbara i Python Jämför: skulle vi vilja mutera värdet 7093 till (säg) 8093, om vi kunde? 16 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K I stället för mutation Så hur gör man om man har en strängvariabel greeting och absolut vill "ändra" dess första tecken till 'J' men bevara alla andra? Svar: man bygger det nya strängvärde man är ute efter! >>> newGreeting = 'J' + greeting[1:] Jämför att bygga ett nytt heltalsvärde: >>> newInt = 8000 + oldInt%1000 Jämför också med att binda om variabler till nya värden: >>> greeting = 'J' + greeting[1:] >>> i = i+1 Detta till trots är mutation ett viktigt begrepp inom programmering, vilket vi ska se redan nästa föreläsning! 17 INTRODUKTION TILL PROGRAMMERING D0009E INTRODUKTION TILL PROGRAMMERING D0009E Exempel Sök rätt på det index där tecknet ch förekommer första gången i strängen str: def find(str, ch): index = 0 while index < len(str): if str[index] == ch: return index index = index + 1 return -1 Notera: en return-sats inuti en snurra. När denna sats exekveras termineras både snurran och den omgivande funktionen omedelbart 18 3 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K Ytterligare ett exempel INTRODUKTION TILL PROGRAMMERING D0009E Modulen string Räkna hur många gånger tecknet 'a' förekommer i strängen "banana": fruit = "banana" count = 0 for char in fruit: if char == ’a’: count = count + 1 print count Importeras på vanligt sätt: import string Kan denna kod generaliseras och inkapslas? (Självklart svar: ja! Se övningar kap 7) (Kom ihåg: tecken är identiska med strängar av längden 1 i Python, och att både " och ' kan omsluta strängar) Innehåller bl a en variant på vår funktion find: >>> string.find("banana", 'a') 1 Denna find accepterar även söksträngar av längd > 1: >>> string.find("banana", 'na') 2 OBS: string.find är också en metod – mer om det i kap 14! 19 20 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K Teckenklasser INTRODUKTION TILL PROGRAMMERING D0009E Att analysera tecken Användbara namn definierade i modulen string: >>> print string.lowercase abcdefghijklmnopqrstuvwxyz >>> print string.uppercase ABCDEFGHIJKLMNOPQRSTUVWXYZ >>> print string.digits 0123456789 >>> print string.punctuation !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ Också användbar, men kanske inte just för utskrift: >>> print string.whitespace Är tecknet ch ett siffertecken? def isDigit(ch): return string.find(string.digits, ch) != -1 Samma sak kan skrivas med den inbyggda operatorn in: def isDigit(ch): return ch in string.digits Ytterligare ett alternativ (drar nytta av att ASCIItabellen håller ihop siffertecknen som ett intervall): def isDigit(ch): return '0' <= ch <= '9' >>> 21 22 L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K INTRODUKTION TILL PROGRAMMERING D0009E L U L E Å T E K N I S K A U N I V E R S I T ET SY S T E M T E K N I K Konvertering INTRODUKTION TILL PROGRAMMERING D0009E Konvertering Från sträng till heltal: def strToInt(str): num = 0 i=0 while i < len(str) and isDigit(str[i]): num = num*10 + ord(str[i]) - ord('0') i = i+1 return num Från heltal till sträng: def intToStr(num): if num==0: return "0" str = "" while num!=0: str = chr(num%10 + ord('0')) + str num = num/10 return str Den inbyggda funktionen int(str) är en variant av denna, fast utökad till att klara även flyttal och andra data som argument Den inbyggda funktionen str(num) är en variant av denna, fast utökad till att klara även flyttal och andra data som argument 23 24 4