2015-10-17 7 views
6

नीचे [अजगर 3.4] एक सरल एरेटोस्थेनेज चलनी है कार्यक्रम:पायथन जेनरेटर; दो जाहिरा तौर पर समान कार्यक्रमों अलग तरह से काम

from itertools import * 
def excl(ns,pr): 
    return (i for i in ns if i%pr) 
def sieve(ns): 
    while True: 
     pr=next(ns) 
     yield pr 
     ns=excl(ns,pr) 
     # ns=(i for i in ns if i%pr) 
r=list(islice(sieve(count(2)),10)) 

जो [2, 3, 5, 7, 11, 13, 17, 19, 23, 29 का उत्पादन ]। ठीक। लाइन को अनदेखा करना जो excl(), और कॉल पर टिप्पणी करता है, [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] देता है। क्यूं कर?

क्या यह उस लूप के अंदर अनुक्रम को मॉडिफ़ करते समय अपेक्षित परेशानियों से संबंधित है, जो इसके ऊपर पुनरावृत्त करता है?

किसी भी संकेत के लिए धन्यवाद।

उत्तर

2

आपका समस्या यह है कि pr जनरेटर अभिव्यक्ति से जाना जाता ही pr है कि आप अपने जबकि पाश की अगले चरण में संशोधित, इसलिए हर संख्या कि विभाज्य नहीं है द्वारा पिछले 'प्रधानमंत्री' नंबर इलाज किया जाता है 'प्राइम' के रूप में। जो स्वयं pr और अन्य में संशोधित करता है। excl फ़ंक्शन में, pr जो आप संदर्भित करते हैं वह एक तर्क के रूप में पारित होता है, जो कभी भी नहीं बदलता है।

+0

मुझे यकीन नहीं है कि मैं यह जवाब समझता हूं। प्राइम पीआर excl (न ही gen.expression में) में बदलता है, यह लूप के भीतर बदलता है, और यह संदर्भ इनलाइन और 'कॉल' संस्करण के लिए समान है। बीटीडब्ल्यू मैंने फिल्टर() के बारे में एक गलत टिप्पणी हटा दी। –

+0

@JerzyKarczmarczuk [पीईपी 227] के अनुसार (https://www.python.org/dev/peps/pep-0227/), यदि किसी कोड ब्लॉक (नेस्टेड फ़ंक्शन) के भीतर कोई नाम उपयोग किया जाता है, लेकिन यह वहां बाध्य नहीं है और वैश्विक घोषित नहीं किया गया है, उपयोग ** ** निकटतम संलग्न समारोह क्षेत्र के संदर्भ के रूप में ** इलाज किया जाता है। चूंकि यह आपके मामले पर लागू होता है, जनरेटर अभिव्यक्ति हुड के नीचे एक फ़ंक्शन है, और यह चर 'pr' को परिभाषित नहीं करता है, इसलिए इसके 'pr' संलग्न कार्य में' pr' को ** संदर्भ ** है। 'sieve')। जिसका अर्थ है कि जब 'चलनी' में 'pr' बदलता है, तो जेनरेटर अभिव्यक्ति में 'pr' भी होता है। – ppperry

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