क्या एक अनंत जनरेटर के लिए एक अभिव्यक्ति है?


119

क्या एक सीधे-सीधे जनरेटर की अभिव्यक्ति है जो अनंत तत्वों का उत्पादन कर सकती है?

यह विशुद्ध सैद्धांतिक सवाल है। यहां "व्यावहारिक" उत्तर की आवश्यकता नहीं है :)


उदाहरण के लिए, एक परिमित जनरेटर बनाना आसान है:

my_gen = (0 for i in xrange(42))

हालाँकि, एक अनंत बनाने के लिए मुझे एक फर्जी कार्य के साथ अपने नाम स्थान को "प्रदूषित" करने की आवश्यकता है:

def _my_gen():
    while True:
        yield 0
my_gen = _my_gen()

एक अलग फ़ाइल में बातें करना और- importबाद में गिनती नहीं है।


मुझे यह भी पता है कि itertools.repeatठीक यही करता है। मैं उत्सुक हूँ अगर वहाँ बिना एक लाइनर समाधान है।


9
आपको वास्तव में अपने नेमस्पेस को प्रदूषित करने की आवश्यकता नहीं है ... बस फ़ंक्शन को नाम दें my_genऔर फिर करें my_gen = my_gen()
६५०२

2
del _my_genयदि आप दो को भ्रमित नहीं करना चाहते हैं तो भी इस्तेमाल कर सकते हैं
जॉन ला रोय

जवाबों:


133
for x in iter(int, 1): pass
  • दो-तर्क iter= शून्य-तर्क कॉल करने योग्य + प्रहरी मूल्य
  • int() हमेशा लौटता है 0

इसलिए, iter(int, 1)एक अनंत पुनरावृत्ति है। स्पष्ट रूप से इस विशेष विषय पर विविधताओं की एक बड़ी संख्या है (विशेषकर एक बार जब आप lambdaमिश्रण में जोड़ते हैं )। विशेष रूप से नोट का एक प्रकार है iter(f, object()), जैसा कि हौसले से बनाई गई वस्तु के रूप में प्रहरी मूल्य का उपयोग करते हुए लगभग एक अनंत पुनरावृत्ति की गारंटी देता है, भले ही पहले तर्क के रूप में इस्तेमाल किए जाने योग्य कॉलबल की परवाह किए बिना।


3
बहुत ही दिलचस्प तरीके से उपयोग करने iterसंपत्ति के साथ intजो हम कई बार भूल जाते हैं।
सेंथिल कुमारन

3
आप अनुकरण करने के लिए इस जादुई नुस्खे का उपयोग कर सकते हैं itertools.count:count = lambda start=0, step=1: (start + i*step for i, _ in enumerate(iter(int, 1)))
Coffee_Table

1
बस समझाने के लिए क्या यहाँ पर जा रहा है: जब iterसमारोह दो तर्क के साथ कहा जाता है, यह आम तौर से थोड़ा अलग व्यवहार करती है: iter(callable, sentinel) -> iterator। तर्क 1, callableको पुनरावृति के प्रत्येक पुनरावृत्ति के लिए कहा जाता है, जब तक कि इसका मूल्य वापस नहीं आता sentinel। लेकिन, जैसा कि int()हमेशा वापस आ जाएगी 0, हम कॉल कर सकते हैं int()हमेशा के लिए और कभी नहीं 1. तक पहुँचने के प्रभाव में हो जाएगा ताकि की एक अनंत सूची तैयार 0की
Olsgaard

217

itertools तीन अनंत जनरेटर प्रदान करता है:

मुझे मानक पुस्तकालय में किसी अन्य का पता नहीं है।


चूंकि आपने एक-लाइनर के लिए कहा था:

__import__("itertools").count()

18
पुन: दोहराना (x, टाइम्स = ∞) - जो कोई भी आश्चर्य के लिए कोई प्रतीक नहीं है - तर्क को छोड़ने से दोहराने के लिए हमेशा के लिए चलता है
Mr_and_Mrs_D

अपवादात्मक क्योंकि (ncoghlan का जवाब सीधे ओपी के प्रश्न को संबोधित करता है) यह अधिक सामान्यतः लागू होता है।
ह्यू वाल्टर्स

यह भस्म की तुलना में बहुत अधिक पठनीय की एक बिल्ली है iter(int, 1)। बहुत बुरा itertoolsएक endlessly()विधि नहीं है जिसका एकमात्र उद्देश्य यह कर रहा है; itertools.count()यह सब पठनीय भी नहीं है।
बॉलपॉइंटबैन

19

आप एक कॉल करने योग्य पर पुनरावृति कर सकते हैं जो पुनरावृत्‍ति की तुलना में सदैव अलग है

g1=iter(lambda:0, 1)

8
मैं दोनों से प्यार करता हूं और इससे नफरत करता हूं ... मुझे प्यार है कि यह पूरा करता है कि मैं इतने कम पात्रों में क्या चाहता हूं, लेकिन नफरत करता हूं कि कोई भी कभी भी इसे देखने वाला नहीं है और जानता है कि यह क्या करना है।
आर्टऑफवर्फ

1
iter(यहाँ अतिरिक्त संतरी के साथ) और lambdaयहाँ (किसी भी पारित किए गए मापदंडों के बिना, return 0) के वाक्यविन्यास को जानने का , नफरत करने का एकमात्र स्थान उस गूढ़ है g1
स्लावोमिर लेनार्ट

@ SławomirLenart पुरुषों को यह कभी नहीं मिलता है। यह सिर्फ इतना छोटा था कि मैं 1g स्क्वर्ट कर दिया।
user237419

8

आपका ओएस कुछ ऐसा प्रदान कर सकता है जिसका उपयोग अनंत जनरेटर के रूप में किया जा सकता है। जैसे कि linux पर

for i in (0 for x in open('/dev/urandom')):
    print i

जाहिर है यह उतना कुशल नहीं है

for i in __import__('itertools').repeat(0)
    print i

11
\nसमय-समय पर प्रदर्शित होने वाला / देव / यूरेनियम समाधान टिका है ... स्पष्ट! :)
hugomg

5

कोई भी जो आंतरिक रूप से एक वर्ग / फ़ंक्शन / जनरेटर के रूप में परिभाषित एक और अनंत पुनरावृत्ति का उपयोग नहीं करता है (नहीं -प्रकारक, एक फ़ंक्शन yield)। एक जनरेटर अभिव्यक्ति हमेशा एओटर से पुनरावृत्त होती है और इसके आइटम को फ़िल्टर करने और मैप करने के अलावा कुछ नहीं करती है। आप अनंत वालों के लिए परिमित मदों से केवल साथ जा सकते हैं नहीं mapऔर filter, आप की जरूरत whileहै (या एक forहै कि समाप्त नहीं करता है, जो वास्तव में क्या हम केवल का उपयोग नहीं कर सकते हैं forऔर परिमित iterators)।

सामान्य ज्ञान: PEP 3142 सतही रूप से समान है, लेकिन निकट निरीक्षण पर ऐसा लगता है कि इसके लिए अभी भी forक्लॉज (इसलिए (0 while True)आपके लिए नहीं ) की आवश्यकता है, अर्थात केवल इसके लिए एक शॉर्टकट प्रदान करता है itertools.takewhile


जैसा कि मुझे संदेह है ... क्या हम यह सुनिश्चित कर सकते हैं कि दुरुपयोग के लिए आसानी से उपलब्ध अनंत जनरेटर नहीं है? (अफसोस की बात है, xrange (0,1, -1) काम नहीं करता है ...)
hugomg

2
@ मिस्सिंगो: from itertools import repeat, count, cycleसंभवतः अधिकांश लोगों के लिए "आसानी से उपलब्ध" के रूप में गिना जाता है।
ncoghlan

1
उफ़, मैं 2-तर्क के बारे में भूल गया iter। अनंत
पुनरावृत्तियां

5

बदसूरत और पागल (हालांकि बहुत मज़ेदार), लेकिन आप कुछ ट्रिक्स (बिना अपने नाम के "नामकरण को प्रदूषित किए बिना") का उपयोग करके एक अभिव्यक्ति से अपना इटरेटर बना सकते हैं:

{ print("Hello world") for _ in
    (lambda o: setattr(o, '__iter__', lambda x:x)
            or setattr(o, '__next__', lambda x:True)
            or o)
    (type("EvilIterator", (object,), {}))() } 

आप स्पष्ट रूप से
LISP

1
@Faissaloo वास्तव में ... आप एक पुराने पृष्ठ पर अभी भी अधिक पागल अभिव्यक्ति पा सकते हैं जो मैंने लिखा था: baruchel.github.io/python/2018/06/20/…
थॉमस

2

हो सकता है कि आप डेकोरेटर का उपयोग इस तरह से कर सकें:

def generator(first):
    def wrap(func):
        def seq():
            x = first
            while True:
                yield x
                x = func(x)
        return seq
    return wrap

उपयोग (1):

@generator(0)
def blah(x):
    return x + 1

for i in blah():
    print i

उपयोग (2)

for i in generator(0)(lambda x: x + 1)():
    print i

मुझे लगता है कि उन बदसूरत लोगों से छुटकारा पाने के लिए इसे और बेहतर बनाया जा सकता है ()। हालाँकि यह उस अनुक्रम की जटिलता पर निर्भर करता है जिसे आप बनाने में सक्षम होना चाहते हैं। आम तौर पर बोलना अगर आपके अनुक्रम को फ़ंक्शंस का उपयोग करके व्यक्त किया जा सकता है, तो जनरेटर की सभी जटिलता और सिंथैटिक चीनी एक डेकोरेटर या डेकोरेटर-जैसे फ़ंक्शन के अंदर छिपाई जा सकती है।


9
ओपी एक ऑन्लाइनर के लिए पूछता है और आप ट्रिपल-नेस्टेड defऔर क्लोजर के साथ 10-लाइन डेकोरेटर पेश करते हैं ? ;)

2
@delnan खैर लेकिन अगर आप डेकोरेटर को एक बार परिभाषित करते हैं, तो आपके पास एक लाइनर हो सकता है, नहीं? जैसा कि मैं समझता हूं कि उद्देश्य एक पंक्ति में प्रत्येक अतिरिक्त अनंत जनरेटर को लागू करना है। और यही यहाँ प्रस्तुत है। आपके पास हो सकता है (2^x), आपके पास हो सकता है (x)। यदि आप इसे थोड़ा सा भी सुधार करते हैं, तो यह भी है, आदि
julx

मेरे सवाल का जवाब नहीं है, लेकिन फिर आप उन सभी शराबी को प्यार कैसे नहीं कर सकते हैं? BTW, मुझे पूरा यकीन है कि आप इससे छुटकारा पाकर अतिरिक्त परगनों से छुटकारा पा सकते हैं seqऔर कोड को सीधे वापस wrap
भेज सकते हैं
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.