लटकने का कारण बनता है मैं पाइथन 2.x और 3.x में अंतर्निहित zip
अनुकरण करने वाले 2 कार्यों के साथ प्रयोग कर रहा हूं। पहले एक सूची लौटाता है (पायथन 2.x के रूप में) और दूसरा एक एक जनरेटर समारोह जो एक समय में सेट उसके परिणाम में से एक टुकड़ा रिटर्न (अजगर 3.x के रूप में) है:जनरेटर अभिव्यक्ति का उपयोग करने से पाइथन
def myzip_2x(*seqs):
its = [iter(seq) for seq in seqs]
res = []
while True:
try:
res.append(tuple([next(it) for it in its])) # Or use generator expression?
# res.append(tuple(next(it) for it in its))
except StopIteration:
break
return res
def myzip_3x(*seqs):
its = [iter(seq) for seq in seqs]
while True:
try:
yield tuple([next(it) for it in its]) # Or use generator expression?
# yield tuple(next(it) for it in its)
except StopIteration:
return
print(myzip_2x('abc', 'xyz123'))
print(list(myzip_3x([1, 2, 3, 4, 5], [7, 8, 9])))
यह अच्छी तरह से काम करता है और zip
में निर्मित की उम्मीद उत्पादन देता है:
[('a', 'x'), ('b', 'y'), ('c', 'z')]
[(1, 7), (2, 8), (3, 9)]
तब मैं, अपने (लगभग) बराबर जनरेटर अभिव्यक्ति के साथ tuple()
कॉल के अंतर्गत सूची समझ की जगह वर्ग कोष्ठक []
हटा कर के बारे में सोचा (क्यों जब जनरेटर को अस्थिर एक्सप के लिए ठीक होना चाहिए तो समझ का उपयोग करके एक अस्थायी सूची बनाएं tuple()
द्वारा ected, सही?)
हालांकि, यह पाइथन को लटकने का कारण बनता है। यदि निष्पादन Ctrlसी (विंडोज़ पर आईडीईएल) का उपयोग करके समाप्त नहीं किया गया है, तो अंत में यह MemoryError
अपवाद के साथ कई मिनटों के बाद बंद हो जाएगा।
कोड को डिबग करना (उदाहरण के लिए PyScripter का उपयोग करके) पता चला कि जेनरेटर अभिव्यक्ति का उपयोग होने पर StopIteration
अपवाद कभी नहीं उठाया जाता है। myzip_2x()
के लिए ऊपर पहला उदाहरण कॉल res
को खाली tuples जोड़ने पर रहता है, जबकि myzip_3x()
को दूसरे उदाहरण कॉल tuples (1, 7)
, (2, 8)
, (3, 9)
, (4,)
, (5,)
, ()
, ()
, ()
, ...
अर्जित करता है।
क्या मुझे कुछ याद आ रही है?
और एक अंतिम ध्यान दें: एक ही फांसी व्यवहार प्रदर्शित होता है या its
एक जनरेटर प्रत्येक समारोह (सूची comprehensions tuple()
कॉल में उपयोग किया जाता है जब) की पहली पंक्ति में (its = (iter(seq) for seq in seqs)
का प्रयोग करके) हो जाता है।
संपादित करें:
विवरण के लिएधन्यवाद @Blckknght, तुम सही थे। This message ऊपर जेनरेटर फ़ंक्शन के समान उदाहरण का उपयोग करके क्या हो रहा है, इस बारे में अधिक जानकारी देता है। निष्कर्ष में, जनरेटर अभिव्यक्तियों का उपयोग करके, केवल पाइथन 3.5+ में काम करता है और इसे फ़ाइल के शीर्ष पर from __future__ import generator_stop
कथन की आवश्यकता होती है और को RuntimeError
के साथ बदलकर (फिर, सूची समझों के बजाय जनरेटर अभिव्यक्तियों का उपयोग करते समय) को बदलना पड़ता है।
संपादित करें 2:
ऊपर अंतिम नोट के लिए के रूप में: अगर its
एक जनरेटर हो जाता है (its = (iter(seq) for seq in seqs)
का प्रयोग करके) यह सिर्फ एक यात्रा का समर्थन करेंगे - क्योंकि जनरेटर एक शॉट iterators हैं। इसलिए यह पहली बार समाप्त हो गया है जबकि लूप चलाया जाता है और बाद के लूप पर केवल खाली ट्यूपल्स प्राप्त होते हैं।
मैं किसी भी लूप या फ़ंक्शन के बाहर कोड चलाकर अपने अनुमान की पुष्टि कर सकता हूं। –
इस तरह के एक अच्छा वैचारिक स्पष्टीकरण के लिए धन्यवाद। – John