Таяз көшіру, терең түсінік және қалыпты тапсырма операциялары арасындағы айырмашылық неде?

import copy

a=”deepak”
b=1,2,3,4
c=[1,2,3,4]
d={1:10,2:20,3:30}

a1=copy.copy(a)
b1=copy.copy(b)
c1=copy.copy(c)
d1=copy.copy(d)


print "immutable - id(a)==id(a1)",id(a)==id(a1)
print "immutable   - id(b)==id(b1)",id(b)==id(b1)
print "mutable - id(c)==id(c1)",id(c)==id(c1)
print "mutable   - id(d)==id(d1)",id(d)==id(d1)

Мен келесі нәтижелерді аламын -

immutable - id(a)==id(a1) True
immutable   - id(b)==id(b1) True
mutable - id(c)==id(c1) False
mutable   - id(d)==id(d1) False

Егер тереңірек орындасам -

a1=copy.deepcopy(a)
b1=copy.deepcopy(b)
c1=copy.deepcopy(c)
d1=copy.deepcopy(d)

нәтижелер бірдей -

immutable - id(a)==id(a1) True
immutable   - id(b)==id(b1) True
mutable - id(c)==id(c1) False
mutable   - id(d)==id(d1) False

Егер мен тапсырма бойынша жұмыс жасайтын болсам -

a1=a
b1=b
c1=c
d1=d

онда нәтижелер -

immutable - id(a)==id(a1) True
immutable   - id(b)==id(b1) True
mutable - id(c)==id(c1) True
mutable   - id(d)==id(d1) True

Can somebody explain what exactly makes a difference between the copies? Is it something related to mutable & immutable objects? If so, can you please explain it to me?

151

8 жауаптар

Қалыпты тағайындау әрекеттері жаңа айнымалыны бар нысанға бағыттайды. docs шағын және терең көшірмелер арасындағы айырмашылықты түсіндіреді:

Таяз және терең көшіру арасындағы айырмашылық тек қана маңызды   күрделі нысандар (тізімдер немесе басқа нысандарды қамтитын нысандар   класс даналары):      
      
  • Ұсақ көшірме жаңа қосылыс нысанын құрастырады және содан кейін (мүмкіндігіне қарай) түпнұсқада табылған объектілерге сілтемелерді кірістіреді.

  •   
  • Терең көшірме жаңа қосылыс нысанын құрастырады, содан соң рекурсивті түрде оған көшірмелерді   түпнұсқа.

  •   

Мұнда кішкене демонстрация:

import copy

a = [1, 2, 3]
b = [4, 5, 6]
c = [a, b]

Көшіру үшін әдеттегі тағайындау әрекеттерін пайдалану:

d = c

print id(c) == id(d)          # True - d is the same object as c
print id(c[0]) == id(d[0])    # True - d[0] is the same object as c[0]

Мөлдір көшірмені пайдалану:

d = copy.copy(c)

print id(c) == id(d)          # False - d is now a new object
print id(c[0]) == id(d[0])    # True - d[0] is the same object as c[0]

Терең көшірмені пайдалану:

d = copy.deepcopy(c)

print id(c) == id(d)          # False - d is now a new object
print id(c[0]) == id(d[0])    # False - d[0] is now a new object
293
қосылды
@Dshank No. Таяу көшірме жаңа нысанды құрастырады, ал тапсырма бар нысандағы жаңа айнымалыны жай ғана көрсетеді. Бар нысанға кез келген өзгерістер айнымалы мәнге де (тағайындаумен) әсер етеді.
қосылды автор grc, көзі
@Stallman Егер өзгертпелі нысандарды қамтитын құрамдас нысанын көшірмесеңіз, онда өзгермейтін нысандар тек бір рет болады. Ауыстырылатын объектілердегі барлық өзгерістер түпнұсқалы қосылыс нысанында және көшірілген қосылыс нысанында көрсетіледі.
қосылды автор grc, көзі
@Stallman list_ [0] өзгермейді, бірақ сіз оны өзгертіп/өзгертпесіз. Оның орнына list_ [0] .append (9) немесе list_ [0] [0] = 7 .
қосылды автор grc, көзі
@Stallman иә, бұл дұрыс естіледі.
қосылды автор grc, көзі
@grc Таяу көшірме жаңа қосылыс нысанын құрастырады және содан кейін (мүмкіндігінше) түпнұсқада табылған объектілерге сілтемелерді кірістіреді. Меңзегіш көшірмені айнымалы нысанға айналдырғанда, жаңа нысанға көшірілген түпнұсқа әсер етуі мүмкін бе?
қосылды автор Stallman, көзі
@grc Бірақ мысалды көрдім (жаңа жолды осы жерден алып тастаймын) list _ = [[1,2], [3,4]] newlist = list_.copy() list_ [0] = [7, 8] print (list_) print (newlist) newlist әлі күнге дейін [[1, 2], [3, 4]]] дегенді көрсетеді. Бірақ list_ [0] - бұл өзгермейтін тізім.
қосылды автор Stallman, көзі
@grc Мен не істеймін, сілтемесін [7,8] басқа тізімге өзгерту керек, бірақ нақты өзгерту мекен-жайдағы list_ [0] . Бұл пікір дұрыс па?
қосылды автор Stallman, көзі
ұсақ көшірме сияқты бірдей ме?
қосылды автор deeshank, көзі
@grc «Бар нысанға кез-келген өзгерістер айнымалыларға (тағайындаумен) әсер етеді» - бұл сөз тіркейтін нысандар үшін ғана емес, жол, қалқымалы, қапшық сияқты өзгермейтін түрлерге қатысты.
қосылды автор Neerav, көзі
@grc Бұл өте пайдалы пікірталас болды, бірақ менде «философиялық» мәселе бар. Менің ойымша, көптеген жаңашыл бағдарламашылар интуитивті түрде күтуге болады: терең көшіруді жүзеге асыру. Неғұрлым кішкене көшірудің құндылығы бар екенін түсіндіріп бере аласыз ба? Қандай жағдайдың терең көшірмелерін алғымыз келмейді? (Егер мені терең көшіру көпшіліктің уақыттың көбі дұрыс емес екенін қаласа, кешіремін)
қосылды автор Lee88, көзі

Мінсіз нысандар үшін көшірудің қажеті жоқ, себебі деректер ешқашан өзгермейді, сондықтан Python сол деректерді пайдаланады; иелер әрдайым бірдей. Ауыстырылатын нысандар үшін, олар ықтимал өзгере алатындықтан, [ұсақ] көшірме жаңа нысан жасайды.

Терең көшірме кірістірілген құрылымдармен байланысты. Егер Сізде тізімдердің тізімдері болса, онда көшірмелері терең көшірмесі кірістірілген тізімдер де бар, сондықтан бұл рекурсиялық көшірме. Тек көшірменің жаңа сыртқы тізімі бар, бірақ ішкі тізімдер сілтемелер болып табылады.

Тағайындау көшірілмейді. Ол ескі деректерге сілтеме жасайды. Сондықтан сол мазмұнмен жаңа тізім жасау үшін көшіру қажет.

37
қосылды
@Stallman сіз сілтеме жасайтын тізімді өзгертпейсіз, жаңа тізімді жасау және оны көшірмелердің бірінің бірінші элементі ретінде тағайындау. list_ [0] [0] = 7 әрекетін орындап көріңіз
қосылды автор perreal, көзі
Тек көшірменің көмегімен сізде жаңа сыртқы тізім бар, бірақ ішкі тізімдер сілтемелер болып табылады. Ішкі тізімдер үшін көшірілген біреудің түпнұсқасы әсер ете ме? Мен тізімі _ = [[1,2], [3,4]] newlist = list_.copy() list_ [0] = [7,8] және newlist сол қалпында қалады, сондықтан ішкі тізім сілтемелер болып табылады ма?
қосылды автор Stallman, көзі

Графикалық мысалда келесі кодты қалай орындау керектігін қарастырайық:

import copy

class Foo(object):
    def __init__(self):
        pass


a = [Foo(), Foo()]
shallow = copy.copy(a)
deep = copy.deepcopy(a)

enter image description here

10
қосылды

Өзгермейтін нысандар үшін көшірмесін жасау маңызды емес, өйткені олар өзгермейді. Ауыстырылатын нысандар үшін assignment , copy және deepcopy басқаша әрекет етеді. Әрқайсысы туралы мысал келтірейік.

Тапсырма операциясы көзден анықтамаға бағыттайды, мысалы:

>>> i = [1,2,3]
>>> j=i
>>> hex(id(i)), hex(id(j))
>>> ('0x10296f908', '0x10296f908') #Both addresses are identical

Енді i және j бірдей тізімге қатысты. i және j екеуінде де бірдей жад мекенжайы бар. Кез-келген жаңартулар олардың екеуіне де көрініс табады. мысалы:

>>> i.append(4)
>>> j
>>> [1,2,3,4] #Destination is updated

>>> j.append(5)
>>> i
>>> [1,2,3,4,5] #Source is updated

Екінші жағынан, copy және deepcopy айнымалы жаңа көшірмесін жасайды. Енді бастапқы айнымалыға өзгеріс енгізілмейді көшіру айнымалысына және керісінше. Алайда, copy (ұсақ көшірме) , кірістірілген нысандардың көшірмесін жасамайды, кірістірілген нысандардың сілтемесін көшіреді. Deepcopy барлық кірістірілген нысандарды рекурсивті көшіреді.

copy және deepcopy әрекеттерін көрсету үшін кейбір мысалдар:

copy : параметрін қолданып тура тізім үлгісі

>>> import copy
>>> i = [1,2,3]
>>> j = copy.copy(i)
>>> hex(id(i)), hex(id(j))
>>> ('0x102b9b7c8', '0x102971cc8') #Both addresses are different

>>> i.append(4)
>>> j
>>> [1,2,3] #Updation of original list didn't affected copied variable

copy : тармағын қолданып кірістірілген тізім мысалы

>>> import copy
>>> i = [1,2,3,[4,5]]
>>> j = copy.copy(i)

>>> hex(id(i)), hex(id(j))
>>> ('0x102b9b7c8', '0x102971cc8') #Both addresses are still different

>>> hex(id(i[3])), hex(id(j[3]))
>>> ('0x10296f908', '0x10296f908') #Nested lists have same address

>>> i[3].append(6)
>>> j
>>> [1,2,3,[4,5,6]] #Updation of original nested list updated the copy as well

Flat list example using deepcopy:

>>> import copy
>>> i = [1,2,3]
>>> j = copy.deepcopy(i)
>>> hex(id(i)), hex(id(j))
>>> ('0x102b9b7c8', '0x102971cc8') #Both addresses are different

>>> i.append(4)
>>> j
>>> [1,2,3] #Updation of original list didn't affected copied variable

deepcopy : пайдаланып кірістірілген тізім мысалы

>>> import copy
>>> i = [1,2,3,[4,5]]
>>> j = copy.deepcopy(i)

>>> hex(id(i)), hex(id(j))
>>> ('0x102b9b7c8', '0x102971cc8') #Both addresses are still different

>>> hex(id(i[3])), hex(id(j[3]))
>>> ('0x10296f908', '0x102b9b7c8') #Nested lists have different addresses

>>> i[3].append(6)
>>> j
>>> [1,2,3,[4,5]] #Updation of original nested list didn't affected the copied variable    
8
қосылды

a, b, c, d, a1, b1, c1 және d1 - идентификаторларымен бірегей түрде анықталған жадтағы нысандарға сілтеме.

Тапсырма операциясы жадтағы нысанға сілтеме жасайды және жаңа атауға сілтеме береді. c = [1,2,3,4] - бұл төрт бүтін санды қамтитын жаңа тізім нысанын жасайтын және осы нысанға c сілтемесін тағайындайтын тағайындау. c1 = c - бұл сол нысанға ұқсас сілтеме қабылдап, c1 дегенге тағайындайтын тағайындау. Тізім өзгермейтіндіктен, сол тізімге кез келген нәрсе көрінеді, себебі сіз оны c немесе c1 арқылы кіре аласыз ба, олар екеуі бірдей нысанға сілтеме жасайды.

c1=copy.copy(c) is a "shallow copy" that creates a new list and assigns the reference to the new list to c1. c still points to the original list. So, if you modify the list at c1, the list that c refers to will not change.

Көшіру түсінігі бүтін сандар мен жолдар сияқты өзгермейтін нысандарға қатысты емес. Осы нысандарды өзгерте алмайтындықтан, әр түрлі орындардағы жадтағы сол мәннің екі көшірмесін алудың қажеті жоқ. Мәселен, көшіру түсінігі қолданылмайтын бүтін сандар мен жолдар және басқа да нысандар жай ғана қайта тағайындалады. Сол себептен a және b мысалдарыңыз бірдей идентификаторларды береді.

c1=copy.deepcopy(c) is a "deep copy", but it functions the same as a shallow copy in this example. Deep copies differ from shallow copies in that shallow copies will make a new copy of the object itself, but any references inside that object will not themselves be copied. In your example, your list has only integers inside it (which are immutable), and as previously discussed there is no need to copy those. So the "deep" part of the deep copy does not apply. However, consider this more complex list:

e = [[1, 2], [4, 5, 6], [7, 8, 9]]

Бұл басқа тізімдерді қамтитын тізім (сіз оны екі өлшемді массив деп сипаттай аласыз).

Егер сіз e e -де «ұсақ көшірмені» іске қоссаңыз, оны e1 -ге көшіруге болады, тізімнің идентификаторы өзгеретінін білесіз, бірақ тізімнің әрбір көшірмесінде сол үш тізім - ішіндегі бүтін сандар тізімдері. e [0] .append (3) дегенді білдіретін болсақ, e [[1, 2, 3], [4 , 5, 6], [7, 8, 9]] . Бірақ e1 де [[1, 2, 3], [4, 5, 6], [7, 8, 9]]] болады. [[1, 2, 3]) e.append (<10, 11, 12) , [4, 5, 6], [7, 8, 9], [10, 11, 12]] . Бірақ e1 әлі де [[1, 2, 3], [4, 5, 6], [7, 8, 9]]] болады. Себебі, сыртқы тізімдер бастапқыда үш ішкі тізімдерге үш сілтемеден тұратын бөлек нысандар болып табылады. Ішкі тізімдерді өзгертсеңіз, оларды бір данасы немесе екіншісі арқылы қарасаңыз да, сол өзгерістерді көресіз. Егер сыртқы тізімдердің біреуін жоғарыда көрсетілгендей өзгертсеңіз, онда e үш түпнұсқа үш тізімге үш жаңа сілтеме және тағы бір жаңа тізімге сілтеме болады. Және e1 әлі тек түпнұсқа үш сілтемеден тұрады.

«Көшірме көшіру» сыртқы тізімді қайталамай қана қоймай, сонымен қатар тізімдердің ішіне кіріп, ішкі тізімдердің көшірмесін жасайды, сонда екі нәтиже жасалған объектілерде бірдей сілтемелер жоқ (өзгермейтін нысандарға қатысты) . Егер ішкі тізімдерде қосымша тізімдер болса (немесе сөздіктер сияқты басқа нысандар) болса, олар да қайталанатын болады. Бұл «терең көшірменің» «терең» бөлігі.

4
қосылды

Python, басқа нысанға әдетте '=' белгісімен тізімдер, жолдар, диктелер және т.б. сияқты нысандарды тағайындағанда, python сілтеме арқылы көшірмесін жасайды . Яғни, келесідей тізбесі бар:

list1 = [ [ 'a' , 'b' , 'c' ] , [ 'd' , 'e' , 'f' ]  ]

және біз келесі тізімге басқа тізім береміз:

list2 = list1

онда python терминалындағы list2 тізімін басып шығарсақ, біз мұны аламыз:

list2 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f ']  ]

Both list1 & list2 are pointing to same memory location, any change to any one them will result in changes visible in both objects, i.e both objects are pointing to same memory location. If we change list1 like this :

list1[0][0] = 'x’
list1.append( [ 'g'] )

онда list1 және list2 екеуі де болады:

list1 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g'] ]
list2 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g’ ] ]

Енді екі нысан көшірмелік көшірме арқылы көшірілгенде Баяу көшірме мәніне жақындағанда, ата-аналық екеудің екі нысаны бірдей жады орналасуына сілтеме жасайды, бірақ көшірілген нысанның кез-келген жаңа өзгертулері әрқайсысына тәуелсіз болады басқа. Мұны шағын мысалмен түсінейік. Мысалы, бізде бұл шағын кодтық үзінді бар:

import copy

list1 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f ']  ]      # assigning a list
list2 = copy.copy(list1)       # shallow copy is done using copy function of copy module

list1.append ( [ 'g', 'h', 'i'] )   # appending another list to list1

print list1
list1 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g', 'h', 'i'] ]
list2 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f '] ]

хабарлама, list2 әсер етпейді, бірақ егер біз төмендегі нысандарға өзгертулер енгізсек:

list1[0][0] = 'x’

онда both list1 және list2 өзгереді:

list1 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g', 'h', 'i'] ] 
list2 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] ]

Now, Deep copy helps in creating completely isolated objects out of each other. If two objects are copied via Deep Copy then both parent & it’s child will be pointing to different memory location. Example :

import copy

list1 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f ']  ]         # assigning a list
list2 = deepcopy.copy(list1)       # deep copy is done using deepcopy function of copy module

list1.append ( [ 'g', 'h', 'i'] )   # appending another list to list1

print list1
list1 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g', 'h', 'i'] ]
list2 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f '] ]

хабарлама, list2 әсер етпейді, бірақ егер біз төмендегі нысандарға өзгертулер енгізсек:

list1[0][0] = 'x’

онда барлық child нысандары мен ата-аналық нысан әртүрлі жад орналасуына нұсқайды, сондай-ақ list2 әсер етпейді:

list1 = [ [ 'x', 'b', 'c'] , [ 'd', 'e', ' f '] , [ 'g', 'h', 'i'] ] 
list2 = [ [ 'a', 'b', 'c'] , [ 'd', 'e', ' f  ' ] ]

Бұл көмектеседі деп үміттенемін.

1
қосылды

Төменде кодын көшіру әдісімен көшіруге, ұсақ көшірмені (тілге) [:] және терең көшірмені пайдалану арқылы тапсырма арасындағы айырмашылықты көрсетеді. Төменде мысалда айырмашылықтарды анық көрсету арқылы кірістірілген тізімдерді қолданады.

from copy import deepcopy

########"List assignment (does not create a copy) ############
l1 = [1,2,3, [4,5,6], [7,8,9]]
l1_assigned = l1

print(l1)
print(l1_assigned)

print(id(l1), id(l1_assigned))
print(id(l1[3]), id(l1_assigned[3]))
print(id(l1[3][0]), id(l1_assigned[3][0]))

l1[3][0] = 100
l1.pop(4)
l1.remove(1)


print(l1)
print(l1_assigned)
print("###################################")

########"List copy using copy method (shallow copy)############

l2 = [1,2,3, [4,5,6], [7,8,9]]
l2_copy = l2.copy()

print(l2)
print(l2_copy)

print(id(l2), id(l2_copy))
print(id(l2[3]), id(l2_copy[3]))
print(id(l2[3][0]), id(l2_copy[3][0]))
l2[3][0] = 100
l2.pop(4)
l2.remove(1)


print(l2)
print(l2_copy)

print("###################################")

########"List copy using slice (shallow copy)############

l3 = [1,2,3, [4,5,6], [7,8,9]]
l3_slice = l3[:]

print(l3)
print(l3_slice)

print(id(l3), id(l3_slice))
print(id(l3[3]), id(l3_slice[3]))
print(id(l3[3][0]), id(l3_slice[3][0]))

l3[3][0] = 100
l3.pop(4)
l3.remove(1)


print(l3)
print(l3_slice)

print("###################################")

########"List copy using deepcopy ############

l4 = [1,2,3, [4,5,6], [7,8,9]]
l4_deep = deepcopy(l4)

print(l4)
print(l4_deep)

print(id(l4), id(l4_deep))
print(id(l4[3]), id(l4_deep[3]))
print(id(l4[3][0]), id(l4_deep[3][0]))

l4[3][0] = 100
l4.pop(4)
l4.remove(1)

print(l4)
print(l4_deep)
print("##########################")
print(l4[2], id(l4[2]))
print(l4_deep[3], id(l4_deep[3]))

print(l4[2][0], id(l4[2][0]))
print(l4_deep[3][0], id(l4_deep[3][0]))
0
қосылды

GIST қабылдайды: «Қалыпты тағайындауды» пайдаланатын таяз тізімдермен (сублические, жай элементтері жоқ) «ұсақ» тізім жасаған кезде «жанама нәтиже» көтеріледі, содан кейін «қалыпты тапсырма» арқылы осы тізімнің көшірмесін жасайсыз. Бұл «жанама нәтиже» жасалған көшірме тізімінің кез келген элементін өзгерткенде, себебі ол бастапқы тізімнің элементтерін автоматты түрде өзгертеді. copy функциясы ыңғайлы болып келеді, себебі көшірме элементтерін өзгерткенде бастапқы тізім элементтерін өзгертпейді.

Екінші жағынан, copy тізімінде тізімдер бар болса, сондай-ақ «жанама әсері» бар және deepcopy оны шешеді. Мысалы, тізімдерді кірістірген үлкен тізім жасасаңыз, (осы тізімнің түпнұсқасы) көшірмесін жасайсыз. «Жағымсыз әсер» үлкен тізімнің ішкі тізімін автоматты түрде өзгертетін көшірме тізімінің қосалқы тізімін өзгерткен кезде пайда болады. Кейде (кейбір жобаларда) сіз үлкен тізімді (түпнұсқалық тізіміңізді) өзгертпей, сақтап қалғыңыз келіп, оның элементтерінің көшірмелерін жасауға тырысыңыз (қосалқы тізімдер). Ол үшін бұл шешім «жанама әсер» туралы қамқорлық ететін deepcopy пайдалану және түпнұсқа мазмұнды өзгертпей көшіруге мүмкіндік береді.

copy және copy copy әрекеттерінің әртүрлі әрекеттері тек күрделі нысандарға қатысты болады (яғни, тізімдер сияқты басқа нысандарды қамтитын нысандар).

Бұл қарапайым код мысалында көрсетілген айырмашылықтар:

First

copy (ұсақ) өзіндік тізім мен осы тізімнің көшірмесін жасай отырып, қалай әрекет ететінін тексерейік:

import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)

Енді кейбір print сынақтарын іске қосып, түпнұсқа тізімінің көшірме тізіміне қарағанда қалай әрекет етуін көрейік:

original_list және copy_list түрлі мекенжайлары бар

print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328

original_list және copy_list элементтері бірдей мекенжайларға ие

print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440

sub_original_list және copy_list элементтері бірдей мекенжайларға ие

print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x1faef08 0x1faef08

original_list элементтерін өзгерту copy_list элементтерін өзгертпейді

original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]

copy_list элементтерін өзгерту original_list элементтерін өзгертпейді

copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]

original_list sub_elements автоматты түрде өзгерту copy_list под_элементтерін автоматты түрде өзгертеді

original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 7]

copy_list alt_элементтерін өзгерту original_list sub_elements автоматты түрде өзгереді

copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 7]

Second

copycode copy дегенмен бірдей әрекетті орындау арқылы (тізімнің түпнұсқасын және осы тізімнің көшірмесін жасау) қалай әрекет ететінін тексерейік:

import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)

Енді кейбір print сынақтарын іске қосып, түпнұсқа тізімінің көшірме тізіміне қарағанда қалай әрекет етуін көрейік:

import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.deepcopy(original_list)

original_list және copy_list түрлі мекенжайлары бар

print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328

original_list және copy_list элементтері бірдей мекенжайларға ие

print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440

sub_elements of original_list және copy_list түрлі мекенжайлары бар

print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x24eef08 0x24f3300

original_list элементтерін өзгерту copy_list элементтерін өзгертпейді

original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]

copy_list элементтерін өзгерту original_list элементтерін өзгертпейді

copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]

original_list sub_elements өзгерткенде copy_list sub_elements өзгермейді

original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]

copy_list sub_elements өзгертуге original_list sub_elements өзгермейді

copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'd'], 7]
0
қосылды