2017-01-07 11 views
12

मैं List comprehension without [ ] in Python के बारे में पढ़ा अनुकूलन करता है तो अब मुझे पता है किकैसे अजगर सशर्त सूची comprehensions

''.join([str(x) for x in mylist]) 

तेजी से

''.join(str(x) for x in mylist) 

है क्योंकि "सूची comprehensions अत्यधिक अनुकूलित कर रहे हैं"

तो मैं मान लीजिए कि अनुकूलन for अभिव्यक्ति की पार्सिंग पर निर्भर करता है, mylist देखता है, इसकी लंबाई की गणना करता है, और इसे प्री-एलोका में उपयोग करता है सटीक सरणी आकार, जो बहुत सारे पुनर्वितरण को बचाता है।

''.join(str(x) for x in mylist) का उपयोग करते समय, join एक जनरेटर को अंधाधुंध प्राप्त करता है और आकार को पहले बिना जानने के अपनी सूची बनाना होता है।

mylist = [1,2,5,6,3,4,5] 
''.join([str(x) for x in mylist if x < 4]) 

कैसे अजगर सूची समझ के आकार का फैसला करता है:

लेकिन अब इस पर विचार? क्या यह mylist के आकार से गणना की जाती है, और पुनरावृत्तियों के दौरान डाउनसाइज किया जाता है (यदि सूची बड़ी है और स्थिति 99% तत्वों को फ़िल्टर करती है तो बहुत खराब हो सकती है), या यह वापस "वापस नहीं जानता अग्रिम आकार "मामला?

संपादित करें: मैं कुछ छोटे बेंचमार्क किया है और यह एक अनुकूलन है कि पुष्टि करने के लिए लगता है:

एक शर्त के बिना:

import timeit 

print(timeit.timeit("''.join([str(x) for x in [1,5,6,3,5,23,334,23234]])")) 
print(timeit.timeit("''.join(str(x) for x in [1,5,6,3,5,23,334,23234])")) 

पैदावार (अपेक्षित रूप से):

3.11010817019474 
3.3457350077491026 

एक शर्त के साथ:

print(timeit.timeit("''.join([str(x) for x in [1,5,6,3,5,23,334,23234] if x < 50])")) 
print(timeit.timeit("''.join(str(x) for x in [1,5,6,3,5,23,334,23234] if x < 50)")) 

पैदावार:

2.7942209702566965 
3.0316467566203276 

तो सशर्त listcomp अभी भी तेज है।

+1

क्या यह आपके प्रश्न का उत्तर देता है: [सूची समझने वाला जनरेटर अभिव्यक्ति के अजीब समय के परिणाम?] (Http://stackoverflow.com/questions/11964130/list-comprehension-vs-generator-expressions-weird-timeit-results) –

+0

बुरा नहीं है, लेकिन इस सवाल में लूप के लिए _ condition_ की स्थिति कभी नहीं है। केवल अभिव्यक्ति में ही, जिसका अर्थ है कि आकार अग्रिम में जाना जाता है। –

+1

मुझे लगता है कि कैसे पाइथन लिंक किए गए प्रश्न के उपयोग में वाई के लिए xx में x के लिए xx के साथ व्यवहार करता है और 'आपके प्रश्न में x में x x के लिए x <123' के लिए जैसा होना चाहिए, दोनों मामले में पाइथन करते हैं अभिव्यक्ति का मूल्यांकन होने तक परिणामी सूची के आकार को नहीं पता। * (केवल तार्किक धारणा, सुनिश्चित नहीं है कि यह सच है) * –

उत्तर

11

सूची समझ सूची का पूर्व-आकार नहीं है, भले ही वे पूरी तरह से कर सकें। आप एक अनुकूलन की उपस्थिति मान रहे हैं जो वास्तव में नहीं किया जाता है।

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

+0

एक और रहस्य मेरे लिए हल हो गया। धन्यवाद। –

+2

फिर सूची को प्रीलोकेट करने में पर्याप्त लाभ हो सकता है? जैसा कि @ जीन-फ्रैंकोइस ने नोट किया, "यह सूची खराब हो सकती है अगर सूची बड़ी है और स्थिति 99% तत्वों को फ़िल्टर करती है", लेकिन फिर, यह * अच्छा * हो सकता है अगर स्थिति तत्वों में से केवल 1% ! – usr2564301

+0

@ रैडलेक्सस बिल्कुल: यदि संग्रह पर संग्रहीत संग्रह 'सूची' है या ज्ञात-इन-अग्रिम आकार वाला कोई और कोई शर्त नहीं है, तो लूप के लिए कोई डबल "नहीं" है, यह पूर्व-आवंटन के लिए एक विशेष मामला (बहुत आम) हो सकता है सूची का आकार। मौजूदा कोड में 80% समय लागू होगा! –

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