অসীম জেনারেটরের জন্য কি কোনও অভিব্যক্তি রয়েছে?


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()
6502

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)))
কফি_টেবল

1
শুধু ব্যাখ্যা করতে এখানে কি ঘটছে হয়: যখন iter-function দুই আর্গুমেন্ট সহ বলা হয়, এটা সাধারণত চেয়ে একটু ভিন্ন আচরণ করবে: iter(callable, sentinel) -> iterator। 1 টি আর্গুমেন্টকে callableপুনরাবৃত্তির প্রতিটি পুনরাবৃত্তির জন্য বলা হয়, যতক্ষণ না এটি মানটির মান দেয় sentinel। তবে, int()সর্বদা ফিরে আসার মতো 0আমরা int()চিরকালের জন্য কল করতে পারি এবং কখনই 1 এ পৌঁছাতে পারি না এটি 0
কার্যকরভাবে

217

itertools তিনটি অসীম জেনারেটর সরবরাহ করে:

আমি স্ট্যান্ডার্ড লাইব্রেরিতে অন্য কারও সম্পর্কে জানি না।


আপনি যেহেতু ওয়ান-লাইনার চেয়েছিলেন:

__import__("itertools").count()

18
পুনরায়: পুনরাবৃত্তি (x, বার = ∞) - যার জন্য অবাক হয়েছে তার কোনও প্রতীক নেই - যুক্তি বাদ দেওয়া পুনরাবৃত্তি
চালিয়ে যায়

উত্সাহিত করা হয়েছে কারণ (যখন এনকোঘ্লানের উত্তরটি সরাসরি ওপি'র প্রশ্নকে সম্বোধন করে) এটি আরও সাধারণভাবে প্রযোজ্য।
হু ওয়াল্টারস

এটি মোড়ের চেয়ে অনেক বেশি পাঠযোগ্য iter(int, 1)। খুব খারাপ itertoolsকোনও endlessly()পদ্ধতি নেই যার একমাত্র উদ্দেশ্য এটি করছে; itertools.count()না হয় পাঠযোগ্য সব।
বলপয়েন্টবেন 16

19

আপনি কল করতে সক্ষম হয়ে ইটার () এর সেন্ডিনেলের চেয়ে সর্বদা পৃথক ধরণের ফিরে আসতে পারেন

g1=iter(lambda:0, 1)

8
আমি উভয়কেই এটি ভালবাসি এবং ঘৃণা করি ... আমি ভালবাসি যে এটি আমি খুব কম চরিত্রে যা চাই তা অর্জন করে তবে এটি ঘৃণা করে যে কেউ কখনই এটির দিকে তাকাবে না এবং কী করবে বলে জেনে যায়।
আর্টঅফ ওয়ারফেয়ার

1
বাক্য গঠন প্রণালী বুদ্ধিমান iter(অতিরিক্ত প্রহরী এখানে) এবং বাক্য গঠন প্রণালী lambda(এখানে কোনো পাশ পরামিতি ছাড়া শুধু return 0), ঘৃণা করার একমাত্র স্থান, যা হেঁয়ালিপূর্ণ হয় g1
সাওওমির লেনার্ট

@ সাওমিরিলার্ন্ট পুরুষরা কখনই এটি পান না। এটি ঠিক এমনি এমনি ছোট ছিল তাই আমি 1 জি স্কুয়ার্ট করেছিলাম।
ব্যবহারকারী 237419

8

আপনার ওএস এমন কিছু সরবরাহ করতে পারে যা অসীম জেনারেটর হিসাবে ব্যবহার করা যেতে পারে। লিনাক্সের উপর

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এবং সীমাবদ্ধ পুনরাবৃত্তকারী ব্যবহার করতে পারি না )।

ট্রিভিয়া: পিইপি 3142 পৃষ্ঠপোষকভাবে অনুরূপ, তবে কাছাকাছি পরিদর্শন করার পরে মনে হয় এটি এখনও forক্লজ প্রয়োজন (তাই (0 while True)আপনার জন্য না), যা কেবল একটি শর্টকাট সরবরাহ করে itertools.takewhile


যেমনটি আমার সন্দেহ হয়েছিল ... আমরা কি তখন নিশ্চিত হতে পারি যে অপব্যবহারের জন্য সহজেই উপলব্ধ অসীম জেনারেটর নেই? (দুঃখের বিষয়, এক্সরেঞ্জ (0,1, -1) কাজ করে না ...)
hugomg

2
@ মিসিংনো: from itertools import repeat, count, cycleসম্ভবত বেশিরভাগ মানুষের কাছে "সহজেই উপলব্ধ" হিসাবে গণ্য।
এনকোঘ্লান

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,), {}))() } 

আপনি স্পষ্টতই
এলআইএসপি

1
@ ফয়সালু আসলেই ... আমি লিখেছিলাম এমন একটি পুরানো পৃষ্ঠায় আপনি আরও বেশি উন্মাদ প্রকাশ পেতে পারেন:
বারুচেল.

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
@ ডেলান ভাল তবে আপনি যদি একবার ডেকরেটারটি সংজ্ঞায়িত করেন তবে আপনার নিজের একটি লাইনার থাকতে পারে, তাই না? আমি যেমন বুঝতে পারি প্রতিটি অতিরিক্ত অসীম জেনারেটরকে এক লাইনে প্রয়োগ করা purpose এবং এটি এখানে উপস্থাপন করা হয়। আপনি থাকতে পারেন (2^x), আপনি করতে পারেন (x)। আপনি যদি এটির কিছুটা সম্ভবত উন্নত করেন তবে
ফাইবোনচি

আমার প্রশ্নের উত্তর দেয় না, তবে কীভাবে আপনি এই সমস্ত ফ্লফি ক্লোজারকে ভালবাসেন না? বিটিডাব্লু, আমি খুব নিশ্চিত যে আপনি seqকোড থেকে সরাসরি মুক্তি এবং wrap
ইনডেন্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.