অগভীর অনুলিপি, ডিপকপি এবং সাধারণ অ্যাসাইনমেন্ট অপারেশনের মধ্যে পার্থক্য কী?


210
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

অনুলিপিগুলির মধ্যে ঠিক কী পার্থক্য রয়েছে তা কি কেউ ব্যাখ্যা করতে পারেন? এটি কি পরিবর্তনীয় এবং অপরিবর্তনীয় বস্তুর সাথে সম্পর্কিত কিছু? যদি তা হয় তবে আপনি দয়া করে আমাকে এটি ব্যাখ্যা করতে পারেন?

উত্তর:


364

সাধারণ অ্যাসাইনমেন্ট ক্রিয়াকলাপগুলি কেবল নতুন ভেরিয়েবলটি বিদ্যমান অবজেক্টের দিকে নির্দেশ করবে। ডক্স অগভীর ও গভীর কপি মধ্যে পার্থক্য ব্যাখ্যা:

অগভীর এবং গভীর অনুলিপিটির মধ্যে পার্থক্য কেবল যৌগিক অবজেক্টের জন্যই প্রাসঙ্গিক (যে বস্তুগুলিতে অন্যান্য বস্তু যেমন তালিকা বা শ্রেণীর উদাহরণ রয়েছে):

  • একটি অগভীর অনুলিপি একটি নতুন যৌগিক বস্তু তৈরি করে এবং তারপরে (সম্ভাব্য পরিমাণে) এটিতে মূলটিতে পাওয়া বস্তুর জন্য রেফারেন্স সন্নিবেশ করায়।

  • একটি গভীর অনুলিপি একটি নতুন যৌগিক বস্তু তৈরি করে এবং তারপরে, পুনরাবৃত্তভাবে, মূলটিতে পাওয়া বস্তুর মধ্যে অনুলিপি সন্নিবেশ করায়।

এখানে একটি সামান্য বিক্ষোভ:

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

5
অনুমান অগভীর অনুলিপি হিসাবে একই?
দেশংক

35
@ শ্যাশক নং একটি অগভীর অনুলিপি একটি নতুন অবজেক্ট তৈরি করে, অন্যদিকে একটি অ্যাসাইনমেন্ট কেবল বিদ্যমান অবজেক্টে নতুন ভেরিয়েবলকে নির্দেশ করবে। বিদ্যমান অবজেক্টে যে কোনও পরিবর্তন উভয় ভেরিয়েবলকে (অ্যাসাইনমেন্ট সহ) প্রভাবিত করবে।
grc

13
@grc "বিদ্যমান অবজেক্টের যে কোনও পরিবর্তন উভয় ভেরিয়েবলকে (অ্যাসাইনমেন্ট সহ) প্রভাবিত করবে" - এই বিবৃতিটি কেবল পরিবর্তনযোগ্য বস্তুর জন্যই সত্য এবং স্ট্রিং, ফ্লোট, টিপলসের মতো স্থায়ী পরিবর্তনযোগ্য প্রকারের জন্য নয়।
নীরভ

1
@grc কিন্তু আমি একটি উদাহরণ চেষ্টা করেছি (আমি এখানে নতুন লাইন মুছে ফেলুন।) এখনো প্রদর্শন । তবে এমন একটি তালিকা যা পরিবর্তনীয়। list_=[[1,2],[3,4]] newlist = list_.copy() list_[0]=[7,8] print(list_) print(newlist)newlist[[1, 2], [3, 4]]list_[0]
অ্যালস্টন

1
@ স্টলম্যান list_[0]পরিবর্তনীয় তবে আপনি এটি পরিবর্তন করছেন / পরিবর্তন করছেন না। চেষ্টা করুন list_[0].append(9)বা list_[0][0] = 7পরিবর্তে।
GRC

46

অপরিবর্তনীয় বস্তুর জন্য, অনুলিপি করার দরকার নেই কারণ ডেটা কখনও পরিবর্তন হবে না, তাই পাইথন একই ডেটা ব্যবহার করে; আইডি সবসময় একই থাকে। পরিবর্তনীয় বস্তুর জন্য, যেহেতু তারা সম্ভাব্যভাবে পরিবর্তন করতে পারে, [অগভীর] অনুলিপি একটি নতুন অবজেক্ট তৈরি করে।

গভীর অনুলিপি নেস্টেড কাঠামোর সাথে সম্পর্কিত। যদি আপনার তালিকাগুলির তালিকা থাকে copiesতবে নেস্টেড তালিকাগুলি ডিপকপি করুন, সুতরাং এটি পুনরাবৃত্তির অনুলিপি। কেবল অনুলিপি সহ, আপনার কাছে একটি নতুন বাইরের তালিকা রয়েছে তবে অভ্যন্তরীণ তালিকাগুলি হল উল্লেখ।

অ্যাসাইনমেন্ট কপি করে না। এটি কেবল পুরানো ডেটার রেফারেন্স সেট করে। সুতরাং একই বিষয়বস্তু সহ একটি নতুন তালিকা তৈরি করতে আপনার অনুলিপি প্রয়োজন।


With just copy, you have a new outer list but inner lists are references.অভ্যন্তরীণ তালিকাগুলির জন্য, অনুলিপিটি কি কোনও মূলটি দ্বারা প্রভাবিত হবে? আমি তালিকার মতো তালিকাগুলি তৈরি করি list_=[[1,2],[3,4]] newlist = list_.copy() list_[0]=[7,8]এবং newlistঅবশেষগুলি একই থাকে, তাই অভ্যন্তরীণ তালিকাটি কি রেফারেন্স হয়?
অ্যালস্টন

1
@ স্টলম্যান আপনি এখানে রেফারেন্সযুক্ত তালিকা পরিবর্তন করছেন না, কেবল একটি নতুন তালিকা তৈরি করুন এবং এটিকে অনুলিপিগুলির মধ্যে প্রথম আইটেম হিসাবে নির্ধারণ করুন। করার চেষ্টা করুনlist_[0][0] = 7
পেরেয়াল

20

অপরিবর্তনীয় বস্তুর জন্য, একটি অনুলিপি তৈরি করা খুব বেশি অর্থবোধ করে না যেহেতু তারা পরিবর্তন করতে চলেছে না। পরিবর্তনীয় বস্তুর জন্য 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(shallow copy)নেস্টেড অবজেক্টগুলির একটি অনুলিপি তৈরি করবেন না, পরিবর্তে এটি কেবল নেস্টেড বস্তুর রেফারেন্সটি অনুলিপি করে। ডিপকপি সমস্ত নেস্ট করা বস্তুগুলি পুনরাবৃত্তভাবে অনুলিপি করে।

এর আচরণ প্রদর্শন করার জন্য কয়েকটি উদাহরণ 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

ফ্ল্যাট তালিকার উদাহরণ ব্যবহার করে 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    

18

নীচের কোডটি কীভাবে কার্যকর করা হয় তা গ্রাফিকাল উদাহরণে দেখি:

import copy

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


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

এখানে চিত্র বর্ণনা লিখুন


5

a, b, c, d, a1, b1, c1 এবং d1 স্মৃতিতে থাকা বস্তুর উল্লেখ, যা তাদের আইডির দ্বারা স্বতন্ত্রভাবে চিহ্নিত করা হয়।

একটি অ্যাসাইনমেন্ট অপারেশন মেমরির মধ্যে অবজেক্টের একটি রেফারেন্স নেয় এবং সেই নতুন রেফারেন্সকে সেই রেফারেন্স দেয়। c=[1,2,3,4]একটি অ্যাসাইনমেন্ট যা এই চারটি পূর্ণসংখ্যার সমন্বিত একটি নতুন তালিকার অবজেক্ট তৈরি করে এবং সেই বস্তুর রেফারেন্স নির্ধারণ করে cc1=cএকটি অ্যাসাইনমেন্ট যা একই অবজেক্টে একই রেফারেন্স নেয় এবং তা নির্ধারণ করে c1। যেহেতু তালিকাটি পরিবর্তনযোগ্য, তাই আপনি যদি এটির মাধ্যমে অ্যাক্সেস করেন cবা না করেই এই তালিকার সাথে যা কিছু ঘটে তা দৃশ্যমান হবে c1কারণ তারা উভয়ই একই বস্তুর রেফারেন্স দেয়।

c1=copy.copy(c)একটি "অগভীর অনুলিপি" যা একটি নতুন তালিকা তৈরি করে এবং এতে নতুন তালিকার রেফারেন্স নির্ধারণ করে c1cএখনও মূল তালিকাতে নির্দেশ করে। সুতরাং, আপনি যদি তালিকাটি এখানে পরিবর্তন করেন তবে c1যে তালিকাটি cউল্লেখ করে তা পরিবর্তন হবে না।

অনুলিপি করার ধারণাটি পূর্ণসংখ্যা এবং স্ট্রিংয়ের মতো অপরিবর্তনীয় বস্তুর সাথে অপ্রাসঙ্গিক। যেহেতু আপনি এই জিনিসগুলি সংশোধন করতে পারবেন না, তাই বিভিন্ন স্থানে মেমরিতে একই মানের দুটি কপি রাখার দরকার নেই। সুতরাং পূর্ণসংখ্যা এবং স্ট্রিংস এবং কিছু অন্যান্য অবজেক্ট যাতে অনুলিপি করার ধারণাটি প্রয়োগ হয় না, কেবল তাদের পুনরায় বরাদ্দ করা হয়। এই কেন আপনার উদাহরণ সাথে আছেন aএবং bঅভিন্ন আইডি স্থাপিত।

c1=copy.deepcopy(c)এটি একটি "গভীর অনুলিপি", তবে এটি এই উদাহরণে অগভীর অনুলিপি হিসাবে একই কাজ করে। গভীর অনুলিপিগুলি অগভীর অনুলিপিগুলির থেকে পৃথক that অগভীর অনুলিপিগুলি বস্তুর নিজস্ব একটি নতুন অনুলিপি তৈরি করবে, তবে সেই বস্তুর অভ্যন্তরের কোনও রেফারেন্সগুলি সেগুলি অনুলিপি করা হবে না। আপনার উদাহরণে, আপনার তালিকার ভিতরে কেবল পূর্ণসংখ্যা রয়েছে (যা অপরিবর্তনীয়) এবং পূর্বে আলোচনা হিসাবে সেগুলি অনুলিপি করার দরকার নেই। সুতরাং গভীর অনুলিপিটির "গভীর" অংশ প্রয়োগ হয় না। তবে, এই আরও জটিল তালিকা বিবেচনা করুন:

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

এটি এমন একটি তালিকা যা অন্যান্য তালিকাগুলি ধারণ করে (আপনি এটি দ্বিমাত্রিক অ্যারে হিসাবেও বর্ণনা করতে পারেন)।

আপনি যদি 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]]। অন্যদিকে, যদি আপনি পরবর্তীকালে করেনি e.append([10, 11, 12]), eহবে [[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12]]। কিন্তু e1এখনও হবে [[1, 2, 3],[4, 5, 6],[7, 8, 9]]। এর কারণ বাহ্যিক তালিকাগুলি পৃথক অবজেক্ট যা প্রাথমিকভাবে প্রত্যেকটিতে তিনটি অভ্যন্তরের তালিকার তিনটি রেফারেন্স থাকে। আপনি যদি অভ্যন্তরীণ তালিকাগুলি সংশোধন করেন তবে আপনি সেগুলি যদি কোনও অনুলিপি বা অন্যটির মাধ্যমে দেখছেন তবে তা পরিবর্তনগুলি দেখতে পাবেন। তবে যদি আপনি উপরের মত বাইরের তালিকার একটি পরিবর্তন করে থাকেন তবেeমূল তালিকার তিনটি রেফারেন্স এবং একটি নতুন তালিকার আরও একটি উল্লেখ রয়েছে। এবং e1এখনও কেবলমাত্র মূল তিনটি রেফারেন্স রয়েছে।

একটি 'গভীর অনুলিপি' কেবল বাহ্যিক তালিকার নকলই করবে না, তবে এটি তালিকার ভিতরেও যাবে এবং অভ্যন্তরীণ তালিকাগুলিগুলিও নকল করবে, যাতে ফলস্বরূপ দুটি বস্তু একই রেফারেন্সের মধ্যে না থাকে (যতদূর পারস্পরিক পরিবর্তনযোগ্য বস্তুর সাথে সম্পর্কিত) । যদি অভ্যন্তরীণ তালিকাগুলির ভিতরে আরও তালিকা (বা অভিধানের মতো অন্যান্য বিষয়) থাকে তবে সেগুলিও নকল হয়ে যায়। এটি 'গভীর অনুলিপি'র' গভীর 'অংশ।


2

পাইথনে, আমরা যখন তালিকা, টুপলস, ডিক ইত্যাদির মতো বস্তুগুলিকে সাধারণত '=' চিহ্ন দিয়ে অন্য কোনও বস্তুর কাছে অর্পণ করি তখন পাইথন রেফারেন্স দ্বারা অনুলিপি তৈরি করে । এটি হ'ল আমাদের এই জাতীয় তালিকার একটি তালিকা রয়েছে:

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

এবং আমরা এই তালিকার মতো আরও একটি তালিকা বরাদ্দ করি:

list2 = list1

তারপরে যদি আমরা পাইথন টার্মিনালে list2 মুদ্রণ করি তবে আমরা এটি পেয়ে যাব:

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

দুটি তালিকা 1 এবং তালিকা 2 একই মেমোরি অবস্থানের দিকে ইঙ্গিত করছে, তাদের যে কোনও একটির পরিবর্তনের ফলে উভয় বস্তুতে দৃশ্যমান পরিবর্তন দেখা যাবে, অর্থাৎ উভয় বস্তু একই মেমরি অবস্থানের দিকে নির্দেশ করছে। যদি আমরা এইভাবে তালিকা 1 পরিবর্তন করি:

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

তাহলে তালিকা 1 এবং তালিকা 2 উভয়ই হবে:

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 '] ]

লক্ষ্য করুন, তালিকা 2 অপরিবর্তিত রয়েছে, তবে আমরা যদি শিশু সামগ্রীতে এমন পরিবর্তন করি:

list1[0][0] = 'x’

তাহলে তালিকা 1 এবং তালিকা 2 উভয়ই পরিবর্তন পাবেন:

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

এখন, ডিপ কপি একে অপরের থেকে সম্পূর্ণ বিচ্ছিন্ন বস্তু তৈরি করতে সহায়তা করে। ডিপ কপির মাধ্যমে যদি দুটি বস্তু অনুলিপি করা হয় তবে পিতা-মাতা এবং তার সন্তান উভয়ই বিভিন্ন মেমরির অবস্থানটির দিকে নির্দেশ করবে। উদাহরণ:

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 '] ]

লক্ষ্য করুন, তালিকা 2 অপরিবর্তিত রয়েছে, তবে আমরা যদি শিশু সামগ্রীতে এমন পরিবর্তন করি:

list1[0][0] = 'x’

তারপরেও তালিকা 2 সমস্ত শিশু বস্তু এবং পিতা-মাতার অবজেক্টকে বিভিন্ন মেমোরি অবস্থানের দিকে চিহ্নিত করার কারণে অকার্যকর হবে:

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

আশা করি এটা সাহায্য করবে.


0

কোডের নীচে অ্যাসাইনমেন্ট, অনুলিপি অনুলিপিটি অনুলিপি পদ্ধতিটি ব্যবহার করে অগভীর অনুলিপি (স্লাইস) [:] এবং ডিপকপি ব্যবহার করে। নীচের উদাহরণে পার্থক্যটিকে আরও সুস্পষ্ট করে সেখানে নেস্টেড তালিকাগুলি ব্যবহার করা হয়েছে।

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

জিআইএসটি নেওয়ার বিষয়টি হ'ল: "সাধারণ অ্যাসাইনমেন্ট" ব্যবহার করে অগভীর তালিকাগুলি (সাব-লিস্ট নয়, কেবলমাত্র একক উপাদান) ব্যবহার করা যখন আপনি অগভীর তালিকা তৈরি করেন তখন আপনি "সাধারণ অ্যাসাইনমেন্ট" ব্যবহার করে এই তালিকার একটি অনুলিপি তৈরি করেন । আপনি তৈরি অনুলিপি তালিকার কোনও উপাদান পরিবর্তন করলে এই "পার্শ্ব প্রতিক্রিয়া" হয়, কারণ এটি স্বয়ংক্রিয়ভাবে মূল তালিকার একই উপাদানগুলিকে পরিবর্তন করবে change এটি তখন কার্যকর হয় যখন copyঅনুলিপি পরিবর্তন করার সময় এটি মূল তালিকা উপাদানগুলিকে পরিবর্তন করে না।

অন্যদিকে, copyআপনার একটি "পার্শ্ব প্রতিক্রিয়া "ও রয়েছে, যখন আপনার একটি তালিকা রয়েছে যাতে এটিতে (সাব_লিস্ট) তালিকা রয়েছে এবং এটি deepcopyসমাধান করে। উদাহরণস্বরূপ, যদি আপনি একটি বৃহত তালিকা তৈরি করেন যা এতে নেস্টেড তালিকাগুলি অন্তর্ভুক্ত করে (সাব_লিস্ট), এবং আপনি এই বড় তালিকার একটি অনুলিপি তৈরি করেন (মূল তালিকা)। আপনি যখন অনুলিপি তালিকার সাব_লিস্টগুলি সংশোধন করেন যা বড় তালিকার সাব_লিস্টগুলি স্বয়ংক্রিয়ভাবে সংশোধন করবে তখন "পার্শ্ব প্রতিক্রিয়া" দেখা দেয়। কখনও কখনও (কিছু প্রকল্পে) আপনি বড় তালিকাটি রাখতে চান (আপনার মূল তালিকাটি) এটি কোনও সংশোধন ছাড়াই রয়েছে এবং আপনি যা চান তা হ'ল এর উপাদানগুলির একটি অনুলিপি (সাব_লিস্ট) তৈরি করা। তার জন্য, আপনার সমাধানটি ব্যবহার করাdeepcopy যা এই "পার্শ্ব প্রতিক্রিয়া" এর যত্ন নেবে এবং মূল সামগ্রীটি পরিবর্তন না করে একটি অনুলিপি তৈরি করে।

বিভিন্ন আচরণে copyএবংdeep copy ক্রিয়াকলাপগুলি কেবল যৌগিক বস্তুগুলিকেই উদ্বেগ করে (যেমন: এমন বস্তুগুলিতে যা অন্যান্য বস্তু যেমন তালিকাগুলি ধারণ করে)।

এই সাধারণ কোড উদাহরণে চিত্রিত পার্থক্য এখানে দেওয়া হল:

প্রথম

copyআসল তালিকা এবং এই তালিকার একটি অনুলিপি তৈরি করে (অগভীর) কীভাবে আচরণ করা যায় তা পরীক্ষা করে দেখুন:

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

এখন, কয়েকটি printপরীক্ষা চালানো যাক এবং আসল তালিকাটি এর অনুলিপি তালিকার তুলনায় কী আচরণ করে:

আসল_লিস্ট এবং কপি_লিস্টের আলাদা ঠিকানা রয়েছে

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

অরিজিনাল লিস্ট এবং কপি লিস্টের উপাদানগুলির একই ঠিকানা রয়েছে

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

অরিজিনাল_লিস্ট এবং কপি_লিস্টের সাব_ এলিমেন্টের একই ঠিকানা রয়েছে

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

অরিজিনাল লিস্ট উপাদানগুলিকে সংশোধন করা অনুলিপি-তালিকার উপাদানগুলিকে পরিবর্তন করে না

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.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[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[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]

দ্বিতীয়

আসুন আমরা কীভাবে deepcopyআচরণ করি তা যাচাই করে দেখি যে আমরা যেমন করেছি 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)

আসল_লিস্ট এবং কপি_লিস্টের আলাদা ঠিকানা রয়েছে

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

অরিজিনাল লিস্ট এবং কপি লিস্টের উপাদানগুলির একই ঠিকানা রয়েছে

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

অরিজিনাল_লিস্ট এবং কপি_লিস্টের সাব-এলিমেন্টের আলাদা ঠিকানা রয়েছে

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

অরিজিনাল লিস্ট উপাদানগুলিকে সংশোধন করা অনুলিপি-তালিকার উপাদানগুলিকে পরিবর্তন করে না

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.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[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[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

এটি উপরে উল্লিখিত হয়েছে কি না তা নিশ্চিত নন, তবে এটি। কপি () মূল অবজেক্টের রেফারেন্স তৈরি করতে খুব আমদানিযোগ্য। যদি আপনি অনুলিপি করা বস্তুটি পরিবর্তন করেন - আপনি আসল বস্তুটি পরিবর্তন করেন। .ডিডি.কপি () নতুন অবজেক্ট তৈরি করে এবং মূল অবজেক্টের নতুন অনুলিপি করে। নতুন ডিপকপিযুক্ত অবজেক্ট পরিবর্তন করা মূল বস্তুকে প্রভাবিত করে না।

এবং হ্যাঁ .ডিপিপি () মূল বস্তুকে পুনরাবৃত্তভাবে অনুলিপি করে, যখন .কপি () মূল বস্তুর প্রথম স্তরের ডেটাতে একটি রেফারেন্স অবজেক্ট তৈরি করে।

সুতরাং .কপি () এবং। ডিডিপিপি () এর মধ্যে অনুলিপি / রেফারেন্সিং পার্থক্যটি উল্লেখযোগ্য।


0

গভীর অনুলিপি নেস্টেড কাঠামোর সাথে সম্পর্কিত। যদি আপনার তালিকাগুলির তালিকা থাকে তবে ডিপকপিটি নেস্টেড তালিকাগুলিও অনুলিপি করে, তাই এটি পুনরাবৃত্তির অনুলিপি। কেবল অনুলিপি সহ, আপনার কাছে একটি নতুন বাইরের তালিকা রয়েছে তবে অভ্যন্তরীণ তালিকাগুলি হল উল্লেখ। অ্যাসাইনমেন্ট কপি করে না। প্রাক্তন জন্য

import copy
spam = [[0, 1, 2, 3], 4, 5]
cheese = copy.copy(spam)
cheese.append(3)
cheese[0].append(3)
print(spam)
print(cheese)

আউটপুট

[[0, 1, 2, 3, 3], 4, 5] [[0, 1, 2, 3, 3], 4, 5, 3] পদ্ধতির অনুলিপি বাইরের তালিকার অনুলিপিটি নতুন তালিকায় অনুলিপি করছেন তবে অভ্যন্তরীণ তালিকাটি উভয় তালিকার জন্য এখনও সমান তাই আপনি যদি কোনও তালিকার অভ্যন্তরীণ তালিকায় পরিবর্তন করেন তবে এটি উভয় তালিকাকেই প্রভাবিত করবে।

তবে আপনি যদি ডিপ অনুলিপি ব্যবহার করেন তবে এটি অভ্যন্তরীণ তালিকার জন্যও নতুন উদাহরণ তৈরি করবে।

import copy
spam = [[0, 1, 2, 3], 4, 5]
cheese = copy.deepcopy(spam)
cheese.append(3)
cheese[0].append(3)
print(spam)
print(cheese)

আউটপুট

[0, 1, 2, 3] [[0, 1, 2, 3, 3], 4, 5, 3]


-1
>>lst=[1,2,3,4,5]

>>a=lst

>>b=lst[:]

>>> b
[1, 2, 3, 4, 5]

>>> a
[1, 2, 3, 4, 5]

>>> lst is b
False

>>> lst is a
True

>>> id(lst)
46263192

>>> id(a)
46263192 ------>  See here id of a and id of lst is same so its called deep copy and even boolean answer is true

>>> id(b)
46263512 ------>  See here id of b and id of lst is not same so its called shallow copy and even boolean answer is false although output looks same.

aএকটি ডিপকপি না lst!
জর্জি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.