2013-07-04 4 views
10

तो सूची लेने और पहले सूची में सदस्यों को जोड़ने के दो तरीके हैं। आप सूची concatenation का उपयोग कर सकते हैं या आप इसे फिर से कर सकते हैं। आप कर सकते हैं:इटरेटिंग बनाम सूची कंसटेनेशन

for obj in list2: 
    list1.append(obj) 

या आप कर सकते हैं:

list1 = list1 + list2 

या

list1 += list2 

मेरे सवाल यह है: जो तेजी से होता है, और क्यों? मैंने दो बेहद बड़ी सूचियों (10000 वस्तुओं के ऊपर) का उपयोग करके इसका परीक्षण किया और ऐसा लगता है कि पुनरावृत्ति विधि सूची संयोजन से बहुत तेज थी (जैसा कि एल 1 = एल 1 + एल 2 में)। ऐसा क्यों है? क्या कोई समझा सकता है?

+0

वे बिल्कुल वही नहीं हैं। –

+1

समय के बारे में प्रश्न पूछते समय, यह एक अच्छा विचार है कि आपने इसका समय कैसे दिखाया है: यह दोनों आपकी तुलना के विवरण दिखाता है और दूसरों को एक नज़र डालने पर एक प्रमुख शुरुआत देता है। –

+0

और 'list1.extend (list2) 'के बारे में क्या? – imkost

उत्तर

13

append एक समय में प्रत्येक आइटम एक है, जो अपनी सुस्ती का कारण है, साथ ही बार-बार समारोह append करने के लिए कॉल कहते हैं।

हालांकि इस मामले += ऑपरेटर नहीं+ के लिए वाक्यात्मक चीनी है में+= ऑपरेटर वास्तव में एक नई सूची नहीं बनाता है, फिर इसे वापस असाइन करता है, यह बाएं हाथ के संचालन को जगह में संशोधित करता है। 10,000 बार दोनों का उपयोग करने के लिए timeit का उपयोग करते समय यह बहुत स्पष्ट है।

>>> timeit.timeit(stmt="l = l + j", setup="l=[1,2,3,4]; j = [5,6,7,8]", number=10000) 
0.5794978141784668 
>>> timeit.timeit(stmt="l += j", setup="l=[1,2,3,4]; j = [5,6,7,8]", number=10000) 
0.0013298988342285156 

+= ज्यादा (500x के बारे में) तेजी से होता है

तुम भी सूचियों के लिए extend विधि है जो की तरह l.extend(l2)

>>> timeit.timeit(stmt="l.extend(j)", setup="l=[1,2,3,4]; j = [5,6,7,8]", number=10000) 
0.0016009807586669922 
>>> timeit.timeit(stmt="for e in j: l.append(e)", setup="l=[1,2,3,4]; j = [5,6,7,8]", number=10000) 
0.00805807113647461 

तार्किक रूप से कुछ के साथ किसी भी iterable (न सिर्फ एक सूची) संलग्न कर सकते हैं संलग्न करने के बराबर, लेकिन आप जितना तेज़ देख सकते हैं उतना तेज़।

तो यह समझाने के लिए: बार-बार दोहराना है तेजी से + क्योंकि + एक पूरी नई सूची

extend यात्रा की तुलना में तेजी है, क्योंकि यह एक builtin सूची विधि है और अनुकूलित किया गया है निर्माण करने के लिए है। तर्कसंगत रूप से बार-बार जोड़ने के बराबर, लेकिन अलग-अलग लागू किया गया।

+=extend से तेज़ है क्योंकि यह सूची में संशोधित कर सकता है, यह जानकर कि सूची कितनी बड़ी होनी चाहिए और बार-बार फ़ंक्शन कॉल के बिना।यह मानता है कि आप अपनी सूची को किसी अन्य सूची/tuple

+0

'+ =' विधि लुकअप नहीं करता है, जाहिर है ('dis' ooutput पर आधारित)। – Elazar

+0

@ '= =' के व्यवहार को कक्षा के '__iadd__' विधि के भीतर परिभाषित किया गया है, इसलिए एक कक्षा जो कुछ भी चाहती है वह कर सकती है। –

+0

'collections.deque' का उपयोग करना भी तेज़ है लेकिन सूचियों के लिए' + = 'जितना तेज़ नहीं है। आप इस 'timeit.timeit (stmt = "l + = j", setup = "संग्रह आयात डेक से जोड़ना चाहते हैं; l = deque ([1,2,3,4]); j = [5,6,7 , 8] ", संख्या = 10000) 'माप तुलना में। – mike

0

मैं निम्नलिखित कोड

l1 = list(range(0, 100000)) 
l2 = list(range(0, 100000)) 

def t1(): 
    starttime = time.monotonic() 
    for item in l1: 
     l2.append(item) 
    print(time.monotonic() - starttime) 

l1 = list(range(0, 100000)) 
l2 = list(range(0, 100000)) 

def t2(): 
    starttime = time.monotonic() 
    global l1 
    l1 += l2 
    print(time.monotonic() - starttime) 

भाग गया और यह मिल गया, जो कहता है कि (+ =) सूचियां जोड़ने का तेजी से होता है।

0,016047026962041855

0,0019438499584794044

+0

रास्ते से पाइथन 3.3 चल रहा है। परिणाम रास्ता और अधिक समझ में आता है क्योंकि सब कुछ के माध्यम से पुनरावृत्ति पार्टी की तरह नहीं लगता है। –

0

के साथ अपनी सूची जोड़ रहे हैं आप गलत माप रहे हैं; append कई बार फ़ंक्शन कॉल (कम से कम cpython) के ओवरहेड के बाद से एक कॉल करने की तुलना में इसे एक कॉल करने से धीमा तरीका है, जो वास्तविक सूची ऑपरेशन के साथ कुछ भी करना है, जैसा कि यहां लिनक्स पर cPython 2.7.5 के साथ दिखाया गया है 64:

$ python -m timeit -s 'x = range(10000);y = range(10000)' 'for e in y:x.append(e)' 
100 loops, best of 3: 2.56 msec per loop 
$ python -m timeit -s 'x = range(10000);y = range(10000)' 'x = x + y' 
100 loops, best of 3: 8.98 msec per loop 
$ python -m timeit -s 'x = range(10000);y = range(10000)' 'x += y' 
10000 loops, best of 3: 105 usec per loop 
$ python -m timeit -s 'x = range(10000);y = range(10000)' 'x.extend(y)' 
10000 loops, best of 3: 107 usec per loop 

ध्यान दें कि x = x + y सूची (कम से कम CPython में) की दूसरी प्रति पैदा करता है। x.extend(y) और उसके चचेरे भाई x += y एक ही चीज करते हैं जैसे कि append कई बार कॉल करना, वास्तव में केवल पाइथन विधि को कॉल करने के ऊपरी हिस्से के बिना।

+0

हास्यास्पद। कमांड लाइन से मापने, '+ = 'और' विस्तार 'बिल्कुल वही हैं, जबकि इंटरैक्टिव दुभाषिया से मापते समय,' + = 'काफी तेज़ है। (Python3.3) – Elazar

संबंधित मुद्दे