পাইথনে লিস্ট কপি/ক্লোন করার নিয়ম

‘=’ অপারেটর ব্যবহার করে পাইথনে এক ভেরিয়েবল থেকে আরেক ভেরিয়েবলে লিস্ট এর ভ্যালু নিয়ে যেতে পারলেও তা ঠিক কপি হয় না । অর্থাৎ আমরা প্রকৃতপক্ষে যে কারনে ‘=’ ব্যবহার করি তা হয় না ।

এই পোস্টে আমি আলোচনা করবো

  • ‘=’ ব্যবহার করলে কি হয়?
  • কেনো ‘=’ ব্যবহার করা উচিত না?
  • লিস্ট কপি/ক্লোন করার কিছু উপায় ।  

 

‘=’ ব্যবহার করলে কি হয়?

New_list = old_list এভাবে কপি করার চেষ্টা করলে প্রকৃতপক্ষে মান কপি হয় না । এ ক্ষেত্রে old_list এর রেফারেন্স new_list ব্যবহার করে । এর ফলে new_list এবং old_list এর নাম আলাদা হলেও দুটো মূলত একই লিস্ট । এর ফলে যে কোন একটির মান পরিবর্তন করলে আরেকটির মানও পরিবর্তন হয়ে যায় ।

কেনো ‘=’ ব্যবহার করা উচিত না ?

‘=’ ব্যবহার করলে যেহেতু রেফারেন্স পাস হয় এবং এর ফলে একটির মান পরিবর্তন করলে আরেকটির মানও পরিবর্তন হয়ে যায়, তাই ‘=’ ব্যবহার করে লিস্ট কপি করার কোন মানেই হয় না ।

যেমন

# create a new list
old_list = [1, 2, 3]

# copy list using = 
new_list = old_list 

# print both lists
print('Before Change') # @output: Before Change
print(old_list) # @output: [1, 2, 3]
print(new_list) # @output: [1, 2, 3]

# now change an element from old_list
old_list[1] = 5 # change second element value from 2 to 5

# again print the lists
print('After Change') # @output: After Change
print(old_list) # @output: [1, 5, 3]
print(new_list) # @output: [1, 5, 3]
				# As = copy the reference 
				# anything changed in old_list
				# will change the value of new_list
				# and vise versa

 

লিস্ট কপি করার কিছু উপায়?

লিস্ট কপি করার অনেক উপায় আছে । আমি এখানে তিনটি নিয়ে কথা বলব ।

 

Slice করে:

এটি সব থেকে দ্রুত লিস্ট এর এলিমেন্টগুলো কপি করে ।  

New_list = old_list[:]

উদাহরণঃ

 

# create a new list
old_list = [1, 2, 3]

# copy list using slice 
new_list = old_list[:] 

# print both lists
print('Before Change') # @output: Before Change
print(old_list) # @output: [1, 2, 3]
print(new_list) # @output: [1, 2, 3]

# now change an element from old_list
old_list[1] = 5 # change second element value from 2 to 5

# again print the lists
print('After Change') # @output: After Change
print(old_list) # @output: [1, 5, 3]
print(new_list) # @output: [1, 2, 3]
				# As slice create a new list and copy the element 
				# anything changed in old_list
				# will not change the value of new_list
				# and vise versa

 

list() ফাংশন ব্যবহার করে:

Slice এর থেকে কিছুটা কম গতির হলেও কোডিং এর ক্ষেত্রে এটি বেশি গ্রহণযোগ্য ।

New_list = list(old_list)

উদাহরণঃ

# create a new list
old_list = [1, 2, 3]

# copy list using list() function 
new_list = list(old_list)

# print both lists
print('Before Change') # @output: Before Change
print(old_list) # @output: [1, 2, 3]
print(new_list) # @output: [1, 2, 3]

# now change an element from old_list
old_list[1] = 5 # change second element value from 2 to 5

# again print the lists
print('After Change') # @output: After Change
print(old_list) # @output: [1, 5, 3]
print(new_list) # @output: [1, 2, 3]
				# As list() create a new list and copy the element 
				# anything changed in old_list
				# will not change the value of new_list
				# and vise versa

 

লিস্ট এর এলিমেন্ট যদি কালেকশন ( list, dictionary, other object ) হয় তবে slice / list() এও কাজ হয় না ।

একটি উদাহরণ দেখি ।

# create a new list
python_language = {'name':'Python 2'}
c_language = {'name':'C'}
go_language = {'name':'go'}
old_language_list = [python_language, c_language]

# copy list using list() function 
new_language_list = list(old_language_list)
# same for
# new_list = old_list[:]

# print both lists
print('Before Change') # @output: Before Change
print(old_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]
print(new_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]

# now add an element to old_list
old_language_list += [go_language]

# again print the lists
print('After Adding a New Element') # @output: After Change
print(old_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}, {'name': 'go'}]
print(new_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]
				# As list() create a new list and copy the element 
				# anything added in old_list
				# will not change the value of new_list
				# and vise versa<span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>

 

এই পর্যন্ত ঠিক আছে । কিন্তু আমরা যদি লিস্ট এর কোন একটি ডিকশনারির মান পরিবর্তন করি, তবে তা সকল লিস্টেই প্রভাব ফেলবে ।

 

# create a new list
python_language = {'name':'Python 2'}
c_language = {'name':'C'}
go_language = {'name':'go'}
old_language_list = [python_language, c_language]

# copy list using list() function 
new_language_list = list(old_language_list)
# same for
# new_list = old_list[:]

# print both lists
print('Before Change') # @output: Before Change
print(old_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]
print(new_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]

# now add an element to old_list
old_language_list += [go_language]

# again print the lists
print('After Adding a New Element') # @output: After Change
print(old_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}, {'name': 'go'}]
print(new_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]
				# As list() create a new list and copy the element 
				# anything added in old_list
				# will not change the value of new_list
				# and vise versa

python_language['name'] = 'Python 3'
# again print the lists
print('After Change an Element') # @output: After Change
print(old_language_list) # @output: [{'name': 'Python 3'}, {'name': 'C'}, {'name': 'go'}]
print(new_language_list) # @output: [{'name': 'Python 3'}, {'name': 'C'

এখানে old_language_list এবং new_language_list এর একটি এলিমেন্ট python_language, তাই python_language এর মান পরিবর্তন করায়  old_language_list এবং new_language_list দুটোতেই প্রভাব পড়েছে । এর কারণ ঐ রেফারেন্স । এজন্য লিস্ট এর এলিমেন্ট যদি অবজেক্ট বা কালেকশন ( লিস্ট, ডিকশনারি, টাপল )  টাইপের হয় তবে সাবধান থাকতে হয়। deepcopy ব্যাবহার করে এ সমস্যা সমাধান করা যায় । 

deepcopy ব্যবহার করে:

স্লো হইলেও অনেকসময় এটি ব্যবহার করতেই হয় । deepcopy প্রতিটি মানের একটি নতুন কপি তৈরি করে । এর ফলে কখনই এক লিস্ট এর মান পরিবর্তন করলে আরেক লিস্ট এ পরিবর্তন হয় না । 

 

import copy

# create a new list
python_language = {'name':'Python 2'}
c_language = {'name':'C'}
go_language = {'name':'go'}
old_language_list = [python_language, c_language]

# copy list using list() function 
new_language_list = copy.deepcopy(old_language_list)


# print both lists
print('Before Change') # @output: Before Change
print(old_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]
print(new_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]

# now add an element to old_list
old_language_list += [go_language]

# again print the lists
print('After Adding a New Element') # @output: After Change
print(old_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}, {'name': 'go'}]
print(new_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]
				# As list() create a new list and copy the element 
				# anything added in old_list
				# will not change the value of new_list
				# and vise versa

python_language['name'] = 'Python 3'
# again print the lists
print('After Change an Element') # @output: After Change
print(old_language_list) # @output: [{'name': 'Python 3'}, {'name': 'C'}, {'name': 'go'}]
print(new_language_list) # @output: [{'name': 'Python 2'}, {'name': 'C'}]

অনিচ্ছাকৃতভাবে ব্যবহার বানান অনেক ক্ষেত্রে ব্যাবহার হয়ে গেছে যা পরবর্তিতে পরিবর্তন করা হয় নি ।

Leave a Reply

Your email address will not be published. Required fields are marked *