महत्वपूर्ण बिंदु यह है कि सूची की समझ एक नई सूची बनाती है। जनरेटर एक चलने वाली वस्तु बनाता है जो बिट्स का उपभोग करने के साथ-साथ-साथ स्रोत सामग्री को "फ़िल्टर" करेगा।
कल्पना करें कि आपके पास एक 2TB लॉग फ़ाइल है, जिसे "vastfile.txt" कहा जाता है, और आप "ENTRY" शब्द से शुरू होने वाली सभी लाइनों के लिए सामग्री और लंबाई चाहते हैं।
तो आप एक सूची समझ लिखकर शुरू करने का प्रयास करें:
logfile = open("hugefile.txt","r")
entry_lines = [(line,len(line)) for line in logfile if line.startswith("ENTRY")]
यह पूरी फ़ाइल को स्लैप करता है, प्रत्येक पंक्ति को संसाधित करता है, और आपके सरणी में मिलान लाइनों को संग्रहीत करता है। इसलिए इस सरणी में 2TB तक की सामग्री हो सकती है। यह बहुत सारे RAM है, और शायद आपके उद्देश्यों के लिए व्यावहारिक नहीं है।
इसलिए इसके बजाय हम अपनी सामग्री के लिए "फ़िल्टर" लागू करने के लिए एक जनरेटर का उपयोग कर सकते हैं। कोई भी डेटा वास्तव में पढ़ा नहीं जाता है जब तक कि हम परिणाम पर चलना शुरू नहीं करते हैं।
logfile = open("hugefile.txt","r")
entry_lines = ((line,len(line)) for line in logfile if line.startswith("ENTRY"))
हमारी फाइल से अभी तक एक भी लाइन नहीं पढ़ी गई है। वास्तव में, मान लें कि हम अपने परिणाम को आगे भी फ़िल्टर करना चाहते हैं:
long_entries = ((line,length) for (line,length) in entry_lines if length > 80)
अभी भी कुछ नहीं पढ़ा गया है, लेकिन हमने अब दो जनरेटर निर्दिष्ट किए हैं जो हमारे डेटा पर काम करेंगे जैसे हम चाहते हैं।
हमारी फ़िल्टर की गई पंक्तियों को किसी अन्य फ़ाइल में लिखें:
outfile = open("filtered.txt","a")
for entry,length in long_entries:
outfile.write(entry)
अब हम इनपुट फाइल को पढ़ते हैं। जैसा कि हमारा for
लूप अतिरिक्त लाइनों का अनुरोध करना जारी रखता है, long_entries
जनरेटर जनरेटर से लाइनों की मांग करता entry_lines
है, केवल उन्हीं को लौटाता है जिनकी लंबाई 80 वर्णों से अधिक होती है। और बदले में, entry_lines
जनरेटर पुनरावृत् तियों (संकेत के अनुसार फ़िल्टर्ड) से अनुरोध करता logfile
है, जो बदले में फ़ाइल को पढ़ता है।
इसलिए पूरी तरह से आबादी वाली सूची के रूप में अपने आउटपुट फ़ंक्शन के लिए डेटा को "पुश" करने के बजाय, आप आउटपुट फ़ंक्शन को केवल तब डेटा "पुल" करने का एक तरीका दे रहे हैं जब इसकी आवश्यकता होती है। यह हमारे मामले में बहुत अधिक कुशल है, लेकिन उतना लचीला नहीं है। जनरेटर एक रास्ता है, एक पास; लॉग फ़ाइल से डेटा जो हमने पढ़ा है वह तुरंत खारिज हो जाता है, इसलिए हम पिछली पंक्ति में वापस नहीं जा सकते। दूसरी ओर, जब भी हम इसके साथ काम करते हैं, तो हमें डेटा रखने की चिंता नहीं करनी चाहिए।
[exp for x in iter]
बस के लिए चीनी होlist((exp for x in iter))
? या वहाँ एक निष्पादन अंतर है?