2011-11-09 11 views
5
old = [1, 2, 3] 

निम्नलिखित दो पंक्तियों (यदि कोई है) के बीच क्या अंतर है?पायथन सूची प्रति: पुरानी [:] और सूची (पुरानी) के बीच कोई अंतर है?

new = old[:] 
new = list(old) 

अद्यतन मैं पहले से ही ubershmekel के जवाब में स्वीकार किया था, लेकिन बाद में मैं एक दिलचस्प तथ्य यह सीखा है: [:] छोटी सूची (10 तत्वों) लेकिन list() के लिए तेजी से होता है है तेजी से बड़ी सूची (100000 तत्व) के लिए।

~$ python -S -mtimeit -s "a = list(range(10))" "a[:]" 
1000000 loops, best of 3: 0.198 usec per loop 
~$ python -S -mtimeit -s "a = list(range(10))" "list(a)" 
1000000 loops, best of 3: 0.453 usec per loop 
~$ python -S -mtimeit -s "a = list(range(100000))" "a[:]" 
1000 loops, best of 3: 675 usec per loop 
~$ python -S -mtimeit -s "a = list(range(100000))" "list(a)" 
1000 loops, best of 3: 664 usec per loop 

उत्तर

5

हां एक छोटा अंतर है। this blog post के बाद हाल ही में /r/python पर एक चर्चा हुई, एक पठनीयता अंतर को समझाया गया, [:] जेनरेटर के साथ काम नहीं करता है और उसी प्रकार को मूल के रूप में रखता है।

तकनीकी रूप से, आपको एक ही चीज़ मिलती है - एक ब्रांड नई सूची जो अभी भी वही ऑब्जेक्ट्स को इंगित करती है। जो भी आप बेहतर पसंद करते हैं चुनें (हालांकि [:] थोड़ा तेज़ है)। व्यक्तिगत रूप से मैं ब्लॉग पोस्ट से सहमत हूं कि list(old) अधिक पठनीय है।

अजगर 3.2 में विशिष्ट अंतर के बारे में टिप्पणी का जवाब करने के लिए,:

>>> import dis 
>>> def colon(x): 
...  return x[:] 
... 
>>> def new_list(x): 
...  return list(x) 
... 
>>> 
>>> dis.dis(colon) 
    2   0 LOAD_FAST    0 (x) 
       3 LOAD_CONST    0 (None) 
       6 LOAD_CONST    0 (None) 
       9 BUILD_SLICE    2 
      12 BINARY_SUBSCR 
      13 RETURN_VALUE 
>>> dis.dis(new_list) 
    2   0 LOAD_GLOBAL    0 (list) 
       3 LOAD_FAST    0 (x) 
       6 CALL_FUNCTION   1 
       9 RETURN_VALUE 
>>> 

क्यों list(old) है धीमी मुझे लगता है कि है, क्योंकि टुकड़ा करने की क्रिया तंत्र को "LOAD_GLOBAL" और "CALL_FUNCTION" की जरूरत नहीं है की सूची पर कन्स्ट्रक्टर, पूरे ऑपरेशन को सी

+0

'[:]' थोड़ा तेज़ क्यों है? –

+0

@ मैटफ़ेनविक की सूची (x) 'को वैश्विक चर' सूची' को देखने और एक तर्क के साथ एक फ़ंक्शन को कॉल करने की आवश्यकता है। 'x [:] 'इनमें से कोई भी नहीं करता है इसलिए इसमें कम ओवरहेड है। यदि यह एक लंबी सूची है तो अंतर छोटा होगा (और शायद एक छोटी सूची के लिए भी महत्वहीन)। – Duncan

+1

पठनीयता कभी-कभी व्यक्तिपरक होती है और पृष्ठभूमि पर निर्भर करती है। उस ब्लॉग या किसी अन्य संबंधित में मैंने पढ़ा [उन्होंने] [:] नोटेशन 'क्रिप्टिक' कहा। अच्छी तरह से ... – joaquin

0

यदि पुराना एक सरणी है, तो दोनों समकक्ष हैं। लेकिन अगर पुराना कुछ प्रकार का इटरेटर है, तो केवल सूची() वाक्यविन्यास काम करेगा। इसी कारण से, दूसरा वाक्यविन्यास संभवतः बेहतर है, क्योंकि यह अधिक सामान्य है।

5

यदि पुरानी सूची नहीं है, तो पुराना [:] पुराने प्रकार के कंटेनर में पुराने (शायद एक टुपल या स्ट्रिंग) जैसा पुराना तत्व होगा, जबकि सूची (पुरानी) एक सूची होगी एक ही तत्व

आईई। यदि पुराना स्ट्रिंग 'foo' है, पुराना [:] स्ट्रिंग 'foo' होगा, जबकि सूची (पुरानी) सूची ['f', 'o', 'o'] होगी।

+0

धन्यवाद, यह प्रासंगिक है, लेकिन मैंने विशेष रूप से उस मामले के बारे में पूछा जब 'पुरानी' एक सूची है (मेरी पहली पंक्ति देखें, 'पुराना = [1, 2, 3] ') – bpgergo

+0

@bpgergo ठीक है, मैंने बस उस पंक्ति को लिया एक पुराना उदाहरण कैसा दिख सकता है इसका एक उदाहरण। वैसे भी, कोई नुकसान नहीं हुआ, मुझे उम्मीद है। :-) –

0

new = old[:] स्लाइस नोटेशन का उपयोग करके सूची old की एक प्रति बनाता है और इसे new में संग्रहीत करता है।

new = list(old)oldlist टाइप करने के लिए रहता है। यह पहले से ही एक सूची है और इसे new में असाइन किया गया है।

मेरा मानना ​​है कि ये दोनों एक ही परिणाम देते हैं। यही है, new में old की एक प्रति शामिल है।

0

किसी ने अभी तक उल्लेख नहीं किया है कि दोनों के बीच यह कार्यात्मक अंतर; सूची (a_generator) काम करेंगे, जबकि a_generator [:] कोई मतलब नहीं है: एक ही तत्वों के साथ एक नया list वस्तु में दोनों परिणाम:

>>> i = iter([1,2,3]) 
>>> i[:] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'listiterator' object is not subscriptable 
>>> list(i) 
[1, 2, 3] 
+0

धन्यवाद, यह प्रासंगिक है, लेकिन मैंने विशेष रूप से उस मामले के बारे में पूछा जब पुरानी सूची है (मेरी पहली पंक्ति, पुरानी = [1, 2, 3] देखें) – bpgergo

0

उदाहरण आप दे, वहाँ कोई अंतर नहीं है।

में सामान्य

  • new = old[:] केवल वस्तुओं है कि स्लाइस समर्थन के साथ काम करेंगे, और new वर्ष
  • के रूप में एक ही प्रकार
  • new = list(old) किसी भी iterable के साथ काम करेंगे हो जाएगा, और new एक list
हो जाएगा
संबंधित मुद्दे