Pridruživanje lista

I u C-u i u pythonu postoje sličnosti pri radu sa stringovima i sa listama (poljima). Najveća razlika između stringova i lista u pythonu dolazi od toga da su stringovi u pythonu nepromjenjivi (immutable):

a = "100"
#a[2] = "1" ovo bi izbacilo grešku

Napomena

U pythonu postoji i immutable verzija liste i taj tip podataka se naziva tuple. Za razliku od liste koja se zadaje uglatim, tuple se zadaje okruglim zagradama npr. a = (1, 2, 3). O razlici lista i tupleova na: http://stackoverflow.com/a/1708538

Pridruživanje vs. shallow copy

Pridruživanjem se ne kopira sadržaj. U sljedećem primjeru a i b pokazuju na isti objekt što znači kad se promijeni a[0], promijeni se i b.
>>> a=[1,2,3]
>>> b=a
>>> a[0]=11
>>> a
[11, 2, 3]
>>> b
[11, 2, 3]
U sljedećem primjeru pomoću a[:] cijeli sadržaj liste je kopiran i ta nova kopija je pridružena varijabli b. Sad možemo mijenjati a neovisno o b.
>>> a=[1,2,3]
>>> b=a[:]
>>> a[0]=11
>>> a
[11, 2, 3]
>>> b
[1, 2, 3]

Shallow copy vs. deep copy

Sad je jasno zašto se ovo zove plitko kopiranje (shallow copy): kopiran je samo prvi nivo liste, drugi nivo je kopiran kao pokazivač, pa u listi b još uvijek “živi” isti objekt c koji živi u a.
>>> c=[4,5,6]
>>> a=[1,2,c]
>>> b=a[:]
>>> a[0]=11
>>> c[0]=44
>>> a
[11, 2, [44, 5, 6]]
>>> b
[1, 2, [44, 5, 6]]
Funkcija copy.deepcopy() služi da se kopiraju svi nivoi liste, tako da su u ovom primjeru a i b potpuno neovisni.
>>> import copy
>>> c=[4,5,6]
>>> a=[1,2,c]
>>> b=copy.deepcopy(a)
>>> a[0]=11
>>> c[0]=44
>>> a
[11, 2, [44, 5, 6]]
>>> b
[1, 2, [4, 5, 6]]

Razne operacije koje sve funkcioniraju kao shallow copy

>>> import copy
>>> c=[4,5,6]
>>> a=[1,2,c]
>>> b=copy.copy(a)
>>> a[0]=11
>>> c[0]=44
>>> a
[11, 2, [44, 5, 6]]
>>> b
[1, 2, [44, 5, 6]]
>>> c=[4,5,6]
>>> a=[1,2,c]
>>> b=list(a)
>>> a[0]=11
>>> c[0]=44
>>> a
[11, 2, [44, 5, 6]]
>>> b
[1, 2, [44, 5, 6]]
>>> c=[4,5,6]
>>> a=[1,2,c]
>>> b=a[:]
>>> a[0]=11
>>> c[0]=44
>>> a
[11, 2, [44, 5, 6]]
>>> b
[1, 2, [44, 5, 6]]
>>> c=[4,5,6]
>>> a=[1,2,c]
>>> b=a+[]
>>> a[0]=11
>>> c[0]=44
>>> a
[11, 2, [44, 5, 6]]
>>> b
[1, 2, [44, 5, 6]]

Usporedba immutable i mutable veličina

Sve varijable u pythonu su interno pointeri. Python u pravilu ne omogućuje očitavanje adresa iako je u nekim implementacijama pythona (npr. u uobičajenoj implementaciji CPython) adresu moguće očitati pomoću id(a). (U C-u: &a.)

immutable mutable mutable
a = "123" # a pokazuje na "123"
b = a     # b pokazuje na isti taj "123"
a = a + "4" # a pokazuje na novi string "1234"
   # b pokazuje još uvijek na onaj stari "123"
print a
print b
1234
123

Treba primijetiti da se b nije promijenio jer se stringovi ne mogu mijenjati, samo može nastati novi string.

a = [1,2,3] # a pokazuje na objekt [1,2,3]
b = a       # b pokazuje na isti taj objekt [1,2,3]
a.append(4) # objekt se promijenio na [1,2,3,4]
print a     # svi koji pokazuju na taj 
print b     #   objekt vide promjenu
[1, 2, 3, 4]
[1, 2, 3, 4]

Treba primijetiti da se i b promijenio zato što je pokazivao na listu koja se u međuvremenu promijenila.

a = [1,2,3]
b = a     
a += [4] 
print a 
print b
[1, 2, 3, 4]
[1, 2, 3, 4]

Isto kao primjer s list.append() (ostale moguće operacije u tablici Mutable Sequence Types).

Literatura