Introduktion till programmering D0009E Föreläsning 7: “Strängar” En

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