2009-07-09 26 views
9

मैं एक csv फ़ाइल से अधिक से अधिक 20 लाइनों को पढ़ने के लिए करना चाहते हैं:पायथन: StopIteration अपवाद और सूची comprehensions

rows = [csvreader.next() for i in range(20)] 

ठीक काम करता है अगर फाइल 20 या अधिक पंक्तियां हैं, एक StopIteration अपवाद अन्यथा के साथ विफल रहता है।

क्या एक इटेटरेटर से निपटने का एक शानदार तरीका है जो सूची समझ में स्टॉपइटरेशन अपवाद फेंक सकता है या क्या मुझे नियमित रूप से लूप का उपयोग करना चाहिए?

उत्तर

11

आप itertools.islice का उपयोग कर सकते हैं। यह सूची स्लाइसिंग का इटरेटर संस्करण है। अगर इटरेटर में 20 से कम तत्व हैं, तो यह सभी तत्वों को वापस कर देगा।

import itertools 
rows = list(itertools.islice(csvreader, 20)) 
+0

धन्यवाद अयमान। ऐसा लगता है कि स्टॉपइटरेशन से निपटने के लिए सूची समझ को अद्यतन करने की आवश्यकता है, नहीं? ऐसा लगता है कि "इसके लिए" पहले से ही इसे अद्यतन करने के लिए अद्यतन किया गया है (यह अपवाद का सामना करते समय इसे फिर से रोकता है, इसे स्पष्ट रूप से पकड़ता है), और मुझे सूची समझों के लिए एक स्पष्ट कारण नहीं दिख रहा है। – Parand

+2

स्टॉपइटरेशन को इसके पुनरुत्थान के सापेक्ष पकड़ने के लिए, अपने सूट में ऐसी अन्य वस्तुओं के लिए नहीं पकड़ता है। उदाहरण c = आईटीईआर (रेंज (5)) रेंज (10) में मैं के लिए के लिए: \t प्रिंट मैं, c.next() ग StopIteration अपवाद रिश्तेदार को बढ़ा देंगे। – Mapio

+3

लूप के लिए ए निश्चित रूप से रोकथाम को पकड़ नहीं लेता है। यह केवल इसे पकड़ता है अगर इसे इटरेटर की अगली विधि द्वारा फेंक दिया जाता है, न कि अगर यह लूप बॉडी में फेंक दिया जाता है। आपके प्रश्न में, csvreader.next() लूप बॉडी के समान है। – Miles

-1

हैं के लिए जो भी कारण आप भी जरूरत लाइन संख्या का ट्रैक रखने के लिए, मैं तुम्हें सलाह देते हैं:

rows = zip(xrange(20), csvreader) 

यदि नहीं, तो आप इसे बाद बाहर पट्टी कर सकते हैं या ... अच्छी तरह से, आप बेहतर दूसरा विकल्प :-)

+0

यदि आपको लाइन नंबर की आवश्यकता है, तो निश्चित रूप से आपको एन्यूमेरेट() .. –

0

itertools.izip (2) शुरू से ही अधिक इष्टतम कोशिश करता हूँ एक तरह से आसानी से सूची comprehensions काम करने के लिए प्रदान करता है, लेकिन islice इस मामले में जाने का रास्ता होने के लिए लग रहा है।

from itertools import izip 
[row for (row,i) in izip(csvreader, range(20))] 
+0

का उपयोग करना चाहिए जिसका लाभ यह है कि यह लेन() के लिए निर्भर नहीं है (उदाहरण के लिए apsw.cursor) – Mark

+0

'enumerate' इसे करने का सही तरीका है , एक रेंज कोई ज़िप नहीं। – ArekBulski