Göm menyn

Muterbarhet

Både listor och strängar låter en komma åt specifika element med operatorn []

>>> "Yolo"[1]
'o'
>>> [5,3,2,1][1]
3

Man kan även ändra innehållet i en lista med samma operator:

>>> seq = [5,3,2,1]
>>> seq[0] = 4
>>> seq
[4,3,2,1]

Men försöker man göra samma sak med en sträng får man följande fel-meddelande:

>>> seq = "Yolo"
>>> seq[0] = "y"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

Detta beror på att listor är muterbara, det vill säga innehållet i en lista kan ändras. Strängar är icke-muterbara, innehållet i en sträng kan inte ändras.

Notera att till skillnad från vissa andra språk så är muterbarheten en egenskap hos värdet, inte hos variabeln. Det går därför bra att göra följande:

>>> seq = "yolo"
>>> seq = "swag"

Detta ändrar ingenting inuti värdet (strängen) "yolo". Det sätter bara om variabeln seq till ett helt annat värde, och det är fullt tillåtet.

Kopiering

I kapitlet om strängar och listor visades metoder som kan se ut som att de ändrar på strängar, till exempel .upper(). Det är dock inte fallet. Dessa ändrar inte en strängen utan skapar en helt ny sträng med nya tecken i. Detta kan ses med följande exempel:

>>> seq = "yolo"
>>> seq.upper()
"YOLO"
>>> seq
"yolo"

Innehållet i strängen "yolo" har inte ändrats, så seq har kvar sitt gamla värde. En ny sträng som bara har stora bokstäver har skapats.

Referenser eller kopior?

Här vill vi påminna om något vi diskuterade redan i samband med funktioner:

  • En variabel innehåller egentligen inte ett värde, såsom talet 3. Deb innehåller alltid en referens till värdet, som säger att "mitt värde ligger där borta". På papperet står alltså en sorts adress: "Mitt värde är lista nummer 14".

Detta kan också kallas en referens till "lista nummer 14".

Vad händer då när man gör följande?

>>> a = [5,2,1]

Nu har vi skapat en lista med värdet [5,2,1]. Låt oss säga att detta blir "lista 42". Variabeln a säger alltså "mitt värde är lista 42".

>>> b = a
>>> b
[5,2,1]

Nu har vi skapat variabeln b. Här kommer Python inte att skapa en ny lista ("lista 43") med samma siffror i. Istället kommer variabeln b också att säga att "mitt värde är lista 42".

>>> b[0] = 3
>>> b
[3,2,1]

Nu har vi ändrat så att första elementet i b är värdet 3. Och b var ju "lista 42", så det är "lista 42" som nu har värdet [3,2,1].

>>> a
[3,2,1]

Och variabeln a var ju också en referens till "lista 42", så när vi tar ut dess värde får vi också ut [3,2,1].

Verkar det konstigt? Vi pratar om referenser, och a och b är två sätt att referera till samma lista. På samma sätt är "Sveriges konung" en referens till en viss person, och "Carl XVI Gustaf" är en annan referens till samma person. Om Sveriges konung åker på statsbesök, har även Carl XVI Gustaf åkt på statsbesök

Om man bara vill ändra på b utan att ändra på a måste man alltså först göra en kopia och sedan göra ändringen i kopian. Detta illustreras i följande figur. Först ser vi varianten där både a och b refererar till samma lista och listans innehåll ändras. Därefer ser vi varianten där a och b först refererar till samma lista, men där man kopierar listan innan man ändrar den ena.

(Texten fortsätter under bilden)

Beskrivning av minnesreferenser

Kopiering av muterbara data kan göras med hjälp av modulen copy

Tupler

Tupler liknar också listor men precis som strängar är de inte muterbara. Man kan till exempel inte byta ut första elementet mot något annat genom att köra tpl[0] = 5.

Det är dock tupeln själv som alltid är icke-muterbar. Dess element kan vara muterbara. I en tupel som innehåller en lista kan man därför inte byta ut listan, men man kan ändra den lista som redan finns i tupeln:

>>> tpl = ([1,2,3], [1,2,3])
>>> tpl[0] = [3,2,1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> tpl[0][0]=0
>>> tpl
([0, 2, 3], [1, 2, 3])

Sammansatta datatyper

Följande tabell beskriver de huvudsakliga egenskaperna hos de sammansatta datatyper vi nu definierat.

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 Många olika datatyper

Tillhörande quiz

Finnes här


Sidansvarig: Peter Dalenius
Senast uppdaterad: 2021-12-03