python - सूची को क्लोन या कॉपी कैसे करें?




list copy (12)

पायथन में एक सूची क्लोन या कॉपी करने के विकल्प क्या हैं?

new_list = my_list का उपयोग करते समय my_list हर बार my_list संशोधित करता है।
ऐसा क्यों है?


पायथन में एक सूची क्लोन या कॉपी करने के विकल्प क्या हैं?

पायथन 3 में, एक उथली प्रतिलिपि बनाई जा सकती है:

a_copy = a_list.copy()

पायथन 2 और 3 में, आप मूल के पूर्ण टुकड़े के साथ एक उथली प्रति प्राप्त कर सकते हैं:

a_copy = a_list[:]

व्याख्या

सूची कॉपी करने के दो अर्थपूर्ण तरीके हैं। एक उथली प्रतिलिपि एक ही वस्तु की एक नई सूची बनाता है, एक गहरी प्रति नई समकक्ष वस्तुओं वाली एक नई सूची बनाता है।

शालो सूची प्रतिलिपि

एक उथली प्रतिलिपि केवल सूची की प्रतिलिपि बनाता है, जो सूची में वस्तुओं के संदर्भों का एक कंटेनर है। यदि ऑब्जेक्ट्स स्वयं निहित हैं और एक बदल गया है, तो परिवर्तन दोनों सूचियों में दिखाई देगा।

पाइथन 2 और 3 में ऐसा करने के कई तरीके हैं। पायथन 2 तरीके पायथन 3 में भी काम करेंगे।

पायथन 2

पायथन 2 में, सूची की उथली प्रतिलिपि बनाने का बेवकूफ तरीका मूल के पूर्ण टुकड़े के साथ है:

a_copy = a_list[:]

आप सूची निर्माता के माध्यम से सूची उत्तीर्ण करके भी वही काम कर सकते हैं,

a_copy = list(a_list)

लेकिन कन्स्ट्रक्टर का उपयोग कम कुशल है:

>>> timeit
>>> l = range(20)
>>> min(timeit.repeat(lambda: l[:]))
0.30504298210144043
>>> min(timeit.repeat(lambda: list(l)))
0.40698814392089844

पायथन 3

पायथन 3 में, सूचियां list.copy विधि प्राप्त करती हैं:

a_copy = a_list.copy()

पायथन 3.5 में:

>>> import timeit
>>> l = list(range(20))
>>> min(timeit.repeat(lambda: l[:]))
0.38448613602668047
>>> min(timeit.repeat(lambda: list(l)))
0.6309100328944623
>>> min(timeit.repeat(lambda: l.copy()))
0.38122922903858125

एक और सूचक बनाना एक प्रतिलिपि नहीं बनाता है

New_list = my_list का उपयोग करते समय my_list में हर बार new_list संशोधित करता है। ऐसा क्यों है?

my_list सिर्फ एक ऐसा नाम है जो स्मृति में वास्तविक सूची को इंगित करता है। जब आप new_list = my_list कहते हैं तो आप एक प्रतिलिपि नहीं बना रहे हैं, तो आप बस एक और नाम जोड़ रहे हैं जो उस मूल सूची में स्मृति में इंगित करता है। जब हम सूचियों की प्रतियां बनाते हैं तो हमारे पास समान समस्याएं हो सकती हैं।

>>> l = [[], [], []]
>>> l_copy = l[:]
>>> l_copy
[[], [], []]
>>> l_copy[0].append('foo')
>>> l_copy
[['foo'], [], []]
>>> l
[['foo'], [], []]

सूची केवल सामग्री के पॉइंटर्स की एक सरणी है, इसलिए एक उथली प्रतिलिपि सिर्फ पॉइंटर्स की प्रतिलिपि बनाता है, और इसलिए आपके पास दो अलग-अलग सूचियां हैं, लेकिन उनके पास एक ही सामग्री है। सामग्री की प्रतिलिपि बनाने के लिए, आपको एक गहरी प्रतिलिपि की आवश्यकता है।

गहरी प्रतियां

सूची की गहरी प्रतिलिपि बनाने के लिए, पायथन 2 या 3 में, copy मॉड्यूल में गहरी प्रतिलिपि का उपयोग करें :

import copy
a_deep_copy = copy.deepcopy(a_list)

यह दिखाने के लिए कि यह हमें नई उप-सूचियां बनाने की अनुमति देता है:

>>> import copy
>>> l
[['foo'], [], []]
>>> l_deep_copy = copy.deepcopy(l)
>>> l_deep_copy[0].pop()
'foo'
>>> l_deep_copy
[[], [], []]
>>> l
[['foo'], [], []]

और इसलिए हम देखते हैं कि गहरी प्रतिलिपि सूची मूल से पूरी तरह से अलग सूची है। आप अपना खुद का काम रोल कर सकते हैं - लेकिन नहीं। आपको मानक लाइब्रेरी के गहरे कॉपी फ़ंक्शन का उपयोग करके अन्यथा आपके पास बग बनाने की संभावना नहीं है।

eval उपयोग न करें

आप इसे गहरे रंग के तरीके के रूप में इस्तेमाल कर सकते हैं, लेकिन ऐसा न करें:

problematic_deep_copy = eval(repr(a_list))
  1. यह खतरनाक है, खासकर यदि आप उस स्रोत से कुछ मूल्यांकन कर रहे हैं जिस पर आप भरोसा नहीं करते हैं।
  2. यह भरोसेमंद नहीं है, अगर आपके द्वारा प्रतिलिपि बनाई गई कोई सबमिशन में कोई प्रतिनिधित्व नहीं है जिसे समकक्ष तत्व को पुन: उत्पन्न करने के लिए eval'd किया जा सकता है।
  3. यह भी कम प्रदर्शनकारी है।

64 बिट पायथन 2.7 में:

>>> import timeit
>>> import copy
>>> l = range(10)
>>> min(timeit.repeat(lambda: copy.deepcopy(l)))
27.55826997756958
>>> min(timeit.repeat(lambda: eval(repr(l))))
29.04534101486206

64 बिट पायथन 3.5 पर:

>>> import timeit
>>> import copy
>>> l = list(range(10))
>>> min(timeit.repeat(lambda: copy.deepcopy(l)))
16.84255409205798
>>> min(timeit.repeat(lambda: eval(repr(l))))
34.813894678023644

चलो शुरुआत से शुरू करते हैं और इसे थोड़ा गहरा खोजते हैं:

तो मान लें कि आपके पास दो सूची हैं:

list_1=['01','98']
list_2=[['01','98']]

और हमें पहली सूची से शुरू होने वाली दोनों सूची कॉपी करना होगा:

तो सबसे पहले कॉपी की सामान्य विधि से आज़माएं:

copy=list_1

अब यदि आप सोच रहे हैं कि प्रतिलिपि सूची_1 की प्रतिलिपि बनाई गई है तो आप गलत हो सकते हैं, चलो इसे जांचें:

The id() function shows us that both variables point to the same list object, i.e. they share this object.
print(id(copy))
print(id(list_1))

उत्पादन:

4329485320
4329485320

आश्चर्य चकित ? ठीक है चलो इसे एक्सप्लोर करें:

इसलिए जैसा कि हम जानते हैं कि पाइथन एक चर में कुछ भी स्टोर नहीं करता है, वेरिएबल्स केवल ऑब्जेक्ट को संदर्भित कर रहे हैं और ऑब्जेक्ट मूल्य को स्टोर करते हैं। यहां ऑब्जेक्ट list लेकिन हमने उसी ऑब्जेक्ट के दो संदर्भ दो अलग-अलग चर नामों से बनाए हैं। तो दोनों चर एक ही वस्तु को इंगित कर रहे हैं:

इसलिए जब आप copy=list_1 करते हैं तो वास्तव में क्या कर रहा है:

यहां छवि सूची_1 में और प्रति दो चर नाम हैं लेकिन ऑब्जेक्ट दोनों चर के लिए समान है जो list

इसलिए यदि आप कॉपी की गई सूची को संशोधित करने का प्रयास करते हैं तो यह मूल सूची को भी संशोधित करेगा क्योंकि सूची केवल एक ही है, आप उस सूची को संशोधित करेंगे चाहे आप कॉपी की गई सूची से या मूल सूची से हों:

copy[0]="modify"

print(copy)
print(list_1)

उत्पादन:

['modify', '98']
['modify', '98']

तो यह मूल सूची में संशोधन किया गया:

तब समाधान क्या है?

उपाय :

अब सूची की प्रतिलिपि बनाने की दूसरी पायथन विधि पर जाएं:

copy_1=list_1[:]

अब यह विधि उस चीज़ को ठीक करती है जिसे हम पहले मुद्दे में सामना कर रहे थे चलो इसे जांचें:

print(id(copy_1))
print(id(list_1))

4338792136
4338791432

इसलिए हम अपनी दोनों सूचीओं को अलग-अलग आईडी देख सकते हैं और इसका मतलब है कि दोनों चर विभिन्न वस्तुओं को इंगित कर रहे हैं, इसलिए वास्तव में यहां क्या चल रहा है:

आइए अब सूची को संशोधित करने का प्रयास करें और देखते हैं कि क्या हमें अभी भी पिछली समस्या का सामना करना पड़ रहा है:

copy_1[0]="modify"

print(list_1)
print(copy_1)

आउटपुट:

['01', '98']
['modify', '98']

इसलिए जब आप देख सकते हैं कि यह मूल सूची को संशोधित नहीं कर रहा है, तो यह केवल कॉपी की गई सूची में संशोधित है, इसलिए हम इसके साथ ठीक हैं।

तो अब मुझे लगता है कि हम कर रहे हैं? प्रतीक्षा करें कि हमें दूसरी नेस्टेड सूची भी कॉपी करनी है, तो चलिए पाइथोनिक तरीके से प्रयास करें:

copy_2=list_2[:]

तो सूची_2 को किसी अन्य ऑब्जेक्ट का संदर्भ देना चाहिए जो सूची 2 की प्रति है, चलिए जांचें:

print(id((list_2)),id(copy_2))

हमें आउटपुट मिलता है:

4330403592 4330403528

अब हम मान सकते हैं कि दोनों सूचियां अलग-अलग ऑब्जेक्ट को इंगित कर रही हैं, इसलिए आइए इसे संशोधित करने का प्रयास करें और देखते हैं कि यह वही है जो हम चाहते हैं:

तो जब हम कोशिश करते हैं:

copy_2[0][1]="modify"

print(list_2,copy_2)

यह हमें आउटपुट देता है:

[['01', 'modify']] [['01', 'modify']]

अब, यह थोड़ा उलझन में है कि हम पाइथोनिक तरीके से इस्तेमाल करते हैं और फिर भी, हम एक ही मुद्दे का सामना कर रहे हैं।

आइए इसे समझें:

तो जब हम करते हैं:

copy_2=list_2[:]

हम वास्तव में केवल बाहरी सूची की प्रतिलिपि बना रहे हैं, न कि नेस्टेड सूची में, इसलिए नेस्टेड सूची दोनों सूची के लिए एक ही वस्तु है, चलिए जांचें:

print(id(copy_2[0]))
print(id(list_2[0]))

उत्पादन:

4329485832
4329485832

तो वास्तव में जब हम copy_2=list_2[:] यह होता है कि:

यह सूची की प्रति बनाता है लेकिन केवल बाहरी सूची प्रतिलिपि, नेस्टेड सूची प्रति नहीं, नेस्टेड सूची दोनों चर के लिए समान है, इसलिए यदि आप नेस्टेड सूची को संशोधित करने का प्रयास करते हैं तो यह मूल सूची को भी संशोधित करेगा क्योंकि नेस्टेड सूची ऑब्जेक्ट दोनों के लिए समान है नेस्टेड सूची।

तो समाधान क्या है?

समाधान deep copy

from copy import deepcopy
deep=deepcopy(list_2)

तो अब इसे जांचें:

print(id((list_2)),id(deep))

उत्पादन:

4322146056 4322148040

दोनों आईडी अलग हैं, अब आइस्टेड सूची आईडी की जांच करें:

print(id(deep[0]))
print(id(list_2[0]))

उत्पादन:

4322145992
4322145800

जैसा कि आप देख सकते हैं कि दोनों आईडी अलग हैं इसलिए हम मान सकते हैं कि दोनों नेस्टेड सूची अब अलग-अलग ऑब्जेक्ट को इंगित कर रही हैं।

तो जब आप deep=deepcopy(list_2) जो वास्तव में होता है:

तो दोनों नेस्टेड सूची अलग-अलग ऑब्जेक्ट को इंगित कर रही हैं और उनके पास अब नेस्टेड सूची की अलग-अलग प्रति है।

आइए अब नेस्टेड सूची को संशोधित करने का प्रयास करें और देखते हैं कि क्या यह पिछले मुद्दे को हल करता है या नहीं:

तो अगर हम करते हैं:

deep[0][1]="modify"
print(list_2,deep)

उत्पादन:

[['01', '98']] [['01', 'modify']]

इसलिए जब आप देख सकते हैं कि यह मूल नेस्टेड सूची को संशोधित नहीं करता है, तो यह केवल कॉपी की गई सूची में संशोधन करता है।

यदि आपको मेरा विस्तृत उत्तर पसंद है, तो मुझे यह बताकर बताएं, अगर आपको कोई संदेह है तो इस जवाब को वास्तविकता दें, टिप्पणी करें :)


अन्य सभी योगदानकर्ताओं ने बहुत अच्छे उत्तर दिए, जो काम करते हैं जब आपके पास एक आयाम ( copy.deepcopy() ) सूची होती है, हालांकि अब तक बताई गई विधियों में से केवल copy.deepcopy() एक सूची क्लोन / कॉपी करने के लिए काम करता है और यह इंगित नहीं करता है नेस्टेड list ऑब्जेक्ट्स जब आप बहुआयामी, नेस्टेड सूचियों (सूचियों की सूची) के साथ काम कर रहे हैं। जबकि ने इसका जवाब अपने संदर्भ में दिया है, इस मुद्दे के लिए थोड़ा और अधिक संभवतः बिल्ट-इन्स का उपयोग करके एक कामकाज है जो deepcopy लिए एक तेज विकल्प साबित कर सकता है।

जबकि new_list = old_list[:] , copy.copy(old_list)' और old_list.copy() के लिए एकल-स्तरीय सूचियों के लिए काम करते हैं, वे old_list और old_list में old_list list ऑब्जेक्ट्स पर इंगित करने के लिए वापस new_list , और एक में परिवर्तन करते हैं list वस्तुओं में से दूसरे में कायम रखा जाता है।

संपादित करें: नई जानकारी प्रकाश में लाई गई

जैसा कि eval() का उपयोग करके और पीएम 2Ring दोनों द्वारा इंगित किया गया था , केवल एक बुरा विचार नहीं है, यह copy.deepcopy() से भी धीमा है।

इसका मतलब है कि बहुआयामी सूचियों के लिए, एकमात्र विकल्प copy.deepcopy() । ऐसा कहा जा रहा है कि, यह वास्तव में एक विकल्प नहीं है क्योंकि जब आप इसे मध्यम आकार के बहुआयामी सरणी पर उपयोग करने का प्रयास करते हैं तो प्रदर्शन दक्षिण में जाता है। मैंने 42x42 सरणी का उपयोग करने का समय निर्धारित करने की कोशिश की, जो कि बायोइनफॉरमैटिक्स अनुप्रयोगों के लिए अनदेखा नहीं था, और मैंने प्रतिक्रिया के लिए इंतजार छोड़ दिया और इस पोस्ट में अपना संपादन टाइप करना शुरू कर दिया।

ऐसा लगता है कि एकमात्र असली विकल्प तब कई सूचियों को शुरू करना और स्वतंत्र रूप से उन पर काम करना है। अगर किसी के पास कोई अन्य सुझाव है, तो बहुआयामी सूची प्रतिलिपि को कैसे संभालना है, इसकी सराहना की जाएगी।

जैसा कि अन्य ने कहा है, बहु-आयामी सूचियों के लिए copy मॉड्यूल और copy.deepcopy का उपयोग करके महत्वपूर्ण प्रदर्शन समस्याएं हो सकती हैंdeepcopy प्रतिलिपि के बिना बहुआयामी सूची की प्रतिलिपि बनाने का एक अलग तरीका काम करने की कोशिश कर रहा है, (मैं एक ऐसे पाठ्यक्रम के लिए समस्या पर काम कर रहा था जो क्रेडिट प्राप्त करने के लिए पूरे एल्गोरिदम चलाने के लिए केवल 5 सेकंड की अनुमति देता है), मैं एक तरह से आया नेस्टेड सूची की प्रतिलिपि बनाने के लिए अंतर्निहित कार्यों का उपयोग करने के लिए उन्हें एक-दूसरे पर या list ऑब्जेक्ट की सूची के बिना। मैंने पुराने सूची की एक लिंक बनाये बिना पुरानी सूची की प्रति नई सूची में कॉपी करने के लिए असाइनमेंट में eval() और repr() का उपयोग किया। यह रूप लेता है:

new_list = eval(repr(old_list))

असल में यह क्या करता है old_list को स्ट्रिंग के रूप में old_list करता है और फिर स्ट्रिंग का मूल्यांकन करता है जैसे कि यह ऑब्जेक्ट होता है जो स्ट्रिंग का प्रतिनिधित्व करता है। ऐसा करके, मूल list ऑब्जेक्ट का कोई लिंक नहीं बनाया गया है। एक नई list वस्तु बनाई गई है और प्रत्येक परिवर्तनीय बिंदु अपने स्वयं के स्वतंत्र वस्तु पर है। यहां 2 आयामी घोंसला वाली सूची का उपयोग करके एक उदाहरण दिया गया है।

old_list = [[0 for j in range(y)] for i in range(x)] # initialize (x,y) nested list

# assign a copy of old_list to new list without them pointing to the same list object
new_list = eval(repr(old_list)) 

# make a change to new_list 
for j in range(y):
    for i in range(x):
    new_list[i][j] += 1

यदि आप प्रत्येक सूची की सामग्री की जांच करते हैं, उदाहरण के लिए 4 से 3 सूची, पायथन वापस आ जाएंगे

>>> new_list

[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]]

>>> old_list

[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

हालांकि यह संभवतः ऐसा करने के लिए कैननिकल या वाक्य रचनात्मक रूप से सही तरीका नहीं है, ऐसा लगता है कि यह अच्छी तरह से काम करता है। मैंने प्रदर्शन का परीक्षण नहीं किया है, लेकिन मुझे लगता है कि eval() और rep() deepcopy की तुलना में चलाने के लिए कम ओवरहेड होगा।


आप सूची () फ़ंक्शन में बुलेट का उपयोग कर सकते हैं:

newlist=list(oldlist)

मुझे लगता है कि यह कोड आपकी मदद करेगा।


पहले से ही कई जवाब हैं जो आपको बताते हैं कि उचित प्रतिलिपि कैसे बनाएं, लेकिन उनमें से कोई भी नहीं कहता कि आपकी मूल 'प्रति' विफल क्यों हुई।

पायथन वैरिएबल में मूल्यों को स्टोर नहीं करता है; यह वस्तुओं को नाम बांधता है। आपके मूल असाइनमेंट ने ऑब्जेक्ट को my_list द्वारा संदर्भित किया और इसे new_list में भी बाध्य कर दिया। इससे कोई फर्क नहीं पड़ता कि आप किस नाम का उपयोग करते हैं, अभी भी केवल एक सूची है, इसलिए इसका जिक्र करते समय किए गए परिवर्तन, क्योंकि my_list इसे my_list रूप में संदर्भित करते समय जारी new_list । इस प्रश्न के अन्य उत्तरों में से प्रत्येक आपको new_list से जुड़ने के लिए एक नई वस्तु बनाने के विभिन्न तरीकों को new_list

सूची का प्रत्येक तत्व किसी नाम की तरह कार्य करता है, जिसमें प्रत्येक तत्व गैर-विशेष रूप से किसी ऑब्जेक्ट को बांधता है। एक उथली प्रतिलिपि एक नई सूची बनाती है जिसका तत्व पहले की तरह एक ही वस्तु से बांधता है।

new_list = list(my_list)  # or my_list[:], but I prefer this syntax
# is simply a shorter way of:
new_list = [element for element in my_list]

अपनी सूची को एक कदम आगे कॉपी करने के लिए, अपनी ऑब्जेक्ट को संदर्भित करने वाली प्रत्येक ऑब्जेक्ट की प्रतिलिपि बनाएँ, और उन तत्व प्रतियों को एक नई सूची में बाध्य करें।

import copy  
# each element must have __copy__ defined for this...
new_list = [copy.copy(element) for element in my_list]

यह अभी तक एक गहरी प्रति नहीं है, क्योंकि किसी सूची का प्रत्येक तत्व अन्य ऑब्जेक्ट्स को संदर्भित कर सकता है, जैसे कि सूची इसके तत्वों से जुड़ी हुई है। सूची में प्रत्येक तत्व को दोबारा प्रतिलिपि बनाने के लिए, और फिर प्रत्येक तत्व द्वारा संदर्भित एक अन्य वस्तु, और इसी तरह: एक गहरी प्रतिलिपि करें।

import copy
# each element must have __deepcopy__ defined for this...
new_list = copy.deepcopy(my_list)

प्रतिलिपि में कोने के मामलों के बारे में अधिक जानकारी के लिए प्रलेखन देखें।


पाइथन संस्करण से स्वतंत्र एक बहुत ही सरल दृष्टिकोण पहले से दिए गए उत्तरों में गायब था, जिसका आप अधिकतर समय उपयोग कर सकते हैं (कम से कम मैं करता हूं):

new_list = my_list * 1       #Solution 1 when you are not using nested lists

हालांकि, अगर my_list में अन्य कंटेनर हैं (उदाहरण के लिए नेस्टेड सूचियों के लिए) आपको प्रतिलिपि लाइब्रेरी से ऊपर दिए गए उत्तरों में सुझाए गए अन्य लोगों के रूप में गहरी प्रतिलिपि का उपयोग करना होगा। उदाहरण के लिए:

import copy
new_list = copy.deepcopy(my_list)   #Solution 2 when you are using nested lists

बोनस : यदि आप तत्वों का उपयोग नहीं करना चाहते हैं (उर्फ उथली प्रतिलिपि):

new_list = my_list[:]

आइए समाधान # 1 और समाधान # 2 के बीच अंतर को समझें

>>> a = range(5)
>>> b = a*1
>>> a,b
([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])
>>> a[2] = 55 
>>> a,b
([0, 1, 55, 3, 4], [0, 1, 2, 3, 4])

जैसा कि आप देख सकते हैं समाधान # 1 पूरी तरह से काम करता है जब हम नेस्टेड सूचियों का उपयोग नहीं कर रहे थे। आइए देखें कि क्या होगा जब हम नेस्टेड सूचियों में समाधान # 1 लागू करते हैं।

>>> from copy import deepcopy
>>> a = [range(i,i+4) for i in range(3)]
>>> a
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
>>> b = a*1
>>> c = deepcopy(a)
>>> for i in (a, b, c): print i   
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
>>> a[2].append('99')
>>> for i in (a, b, c): print i   
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5, 99]]
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5, 99]]   #Solution#1 didn't work in nested list
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]       #Solution #2 - DeepCopy worked in nested list


यह मुझे आश्चर्यचकित करता है कि इसका अभी तक उल्लेख नहीं किया गया है, इसलिए पूर्णता के लिए ...

आप "स्प्लट ऑपरेटर" के साथ अनपॅकिंग सूची निष्पादित कर सकते हैं: * , जो आपकी सूची के तत्वों की प्रतिलिपि भी बनायेगा।

old_list = [1, 2, 3]

new_list = [*old_list]

new_list.append(4)
old_list == [1, 2, 3]
new_list == [1, 2, 3, 4]

इस विधि के स्पष्ट नकारात्मक पक्ष यह है कि यह केवल पायथन 3.5+ में उपलब्ध है।

समय के अनुसार, यह अन्य सामान्य तरीकों से बेहतर प्रदर्शन करने लगता है।

x = [random.random() for _ in range(1000)]

%timeit a = list(x)
%timeit a = x.copy()
%timeit a = x[:]

%timeit a = [*x]

#: 2.47 µs ± 38.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
#: 2.47 µs ± 54.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
#: 2.39 µs ± 58.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

#: 2.22 µs ± 43.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

new_list = list(old_list)


new_list = my_list , आपके पास वास्तव में दो सूचियां नहीं हैं। असाइनमेंट सिर्फ सूची के संदर्भ की प्रतिलिपि बनाता है, वास्तविक सूची नहीं, इसलिए new_list और my_list दोनों असाइनमेंट के बाद एक ही सूची का संदर्भ लें।

वास्तव में सूची की प्रतिलिपि बनाने के लिए, आपके पास विभिन्न संभावनाएं हैं:

  • आप इसे टुकड़ा कर सकते हैं:

    new_list = old_list[:]
    

    इस बारे में एलेक्स मार्टेलि की राय (कम से कम 2007 में ) इस बात के बारे में है कि यह एक अजीब वाक्यविन्यास है और इसका उपयोग कभी भी समझ में नहीं आता है । ;) (उनकी राय में, अगला एक और पठनीय है)।

  • आप अंतर्निहित list() फ़ंक्शन का उपयोग कर सकते हैं:

    new_list = list(old_list)
    
  • आप जेनेरिक copy.copy() उपयोग कर सकते हैं:

    import copy
    new_list = copy.copy(old_list)
    

    यह list() से थोड़ा धीमा है क्योंकि इसे पहले old_list के डेटाटाइप को old_list

  • यदि सूची में ऑब्जेक्ट्स हैं और आप उन्हें कॉपी करना चाहते हैं, तो सामान्य copy.deepcopy() उपयोग करें:

    import copy
    new_list = copy.deepcopy(old_list)
    

    स्पष्ट रूप से सबसे धीमी और सबसे स्मृति-आवश्यकता विधि, लेकिन कभी-कभी अपरिहार्य।

उदाहरण:

import copy

class Foo(object):
    def __init__(self, val):
         self.val = val

    def __repr__(self):
        return str(self.val)

foo = Foo(1)

a = ['foo', foo]
b = a[:]
c = list(a)
d = copy.copy(a)
e = copy.deepcopy(a)

# edit orignal list and instance 
a.append('baz')
foo.val = 5

print('original: %r\n slice: %r\n list(): %r\n copy: %r\n deepcopy: %r'
      % (a, b, c, d, e))

परिणाम:

original: ['foo', 5, 'baz']
slice: ['foo', 5]
list(): ['foo', 5]
copy: ['foo', 5]
deepcopy: ['foo', 1]

वेरिएबल और वैल्यू वाले अन्य भाषाओं के विपरीत, पायथन का नाम और ऑब्जेक्ट है

यह कथन:

a = [1,2,3]

सूची (ऑब्जेक्ट) को एक नाम देने का मतलब है, और, यह:

b = a

बस एक ही ऑब्जेक्ट को a नया नाम b , इसलिए जब भी आप किसी के साथ कुछ करते हैं, ऑब्जेक्ट बदलता है और इसलिए b बदल जाता है।

वास्तव में एक प्रतिलिपि बनाने का एकमात्र तरीका एक नई वस्तु बनाना है जैसे कि पहले से ही अन्य उत्तरों ने कहा है।

आप here इसके बारे में और अधिक देख सकते हैं।


new_list = my_list[:]

new_list = my_list इसे समझने का प्रयास करें। आइए मान लें कि my_list स्थान एक्स पर ढेर मेमोरी में है यानी my_list एक्स को इंगित कर रहा है। अब new_list = my_list असाइन करके आप एक्स को इंगित करने वाली नई_सूची दे रहे हैं। इसे उथले प्रतिलिपि के रूप में जाना जाता है।

अब यदि आप new_list = my_list[:] असाइन करते हैं new_list = my_list[:] आप मेरी mylist की प्रत्येक ऑब्जेक्ट को new_list में कॉपी कर रहे हैं। इसे दीप कॉपी के रूप में जाना जाता है।

अन्य तरीकों से आप यह कर सकते हैं:

  • new_list = list(old_list)
  • import copy new_list = copy.deepcopy(old_list)






clone