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 lista pomoću operatora pridruživanja (=) ne kopira se sadržaj liste.
Samo se varijabli slijeva pridruži postojeća lista navedena desno od operatora pridruživanja.
U sljedećem primjeru vidimo da nakon pridruživanja a i b pokazuju na isti objekt što znači da ako se naknadno promijeni a[0] , promijeni se i b[0] . |
>>> 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¶
U sljedećem primjeru kopiramo listu koja u sebi sadrži referencu na drugu listu.
Za kopiranje koristimo shallow-copy način iz prethodnog primjera.
U prethodnom primjeru, shallow-copy je omogućio da liste a i b budu neovisne.
Ovdje vidimo da to još uvijek vrijedi za prvi nivo liste.
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)
.
Immutable | 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 |
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 |
Mutable (inplace operacija) | Mutable (operacija koja kopira) |
---|---|
a = [1,2,3]
b = a
a += [4]
print(a)
print(b)
[1, 2, 3, 4]
[1, 2, 3, 4]
Isto kao primjer s |
a = [1,2,3]
b = a
a = a + [4]
print(a)
print(b)
[1, 2, 3, 4]
[1, 2, 3]
Iako je tip mutable, kad se umjesto |
Literatura
- https://www.python-course.eu/python3_deep_copy.php
- http://en.wikipedia.org/wiki/Object_copy
- http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy
- https://docs.python.org/3/library/copy.html
- http://stackoverflow.com/questions/17246693/what-exactly-is-the-difference-between-shallow-copy-deepcopy-and-normal-assignm
- na google-u tražiti: shallow deep copy python