পাইথনে জেনারেটর অবজেক্ট পুনরায় সেট করা হচ্ছে


153

আমি এক জেনারেটর বস্তু একাধিক ফলন দ্বারা ফিরে এসেছে। এই জেনারেটরকে কল করার প্রস্তুতি বরং সময়সাপেক্ষ অপারেশন। এজন্য আমি বেশ কয়েকবার জেনারেটরটি পুনরায় ব্যবহার করতে চাই।

y = FunctionWithYield()
for x in y: print(x)
#here must be something to reset 'y'
for x in y: print(x)

অবশ্যই, আমি সাধারণ তালিকায় বিষয়বস্তু অনুলিপি মনে করছি। আমার জেনারেটরটি পুনরায় সেট করার কোনও উপায় আছে?

উত্তর:


119

অন্য বিকল্পটি হ'ল itertools.tee()আপনার জেনারেটরের দ্বিতীয় সংস্করণ তৈরি করতে ফাংশনটি ব্যবহার করা :

y = FunctionWithYield()
y, y_backup = tee(y)
for x in y:
    print(x)
for x in y_backup:
    print(x)

মূল পুনরাবৃত্তি সমস্ত আইটেম প্রক্রিয়া না করতে পারলে স্মৃতি ব্যবহারের দৃষ্টিকোণ থেকে এটি উপকারী হতে পারে।


33
এটি যদি এই ক্ষেত্রে কী করবে তা নিয়ে আপনি যদি ভাবছেন তবে এটি মূলত তালিকার উপাদানগুলিকে ক্যাশে করছে। সুতরাং আপনি পাশাপাশি y = list(y)আপনার বাকী কোডটি অপরিবর্তিত রেখে ব্যবহার করতে পারেন ।
ইলিয়া n।

5
টি () তথ্য সংরক্ষণের জন্য অভ্যন্তরীণভাবে একটি তালিকা তৈরি করবে, যাতে আমি আমার উত্তরে যা করেছি।
nosklo

6
ইমপ্লিমেন্টেশন দেখুন ( ডকস.পিথন.আর.লাইবারি / ডাইরটোজস html # itertools.tee ) - এটি অলস লোড কৌশল ব্যবহার করে, যাতে আইটেমগুলি কেবলমাত্র দাবিতে অনুলিপি করা হয়
ডিউফাই

11
@ ডিউফাই: যা ধীরে ধীরে হবে তাই যেহেতু সমস্ত আইটেম অনুলিপি করতে হবে।
nosklo

8
হ্যাঁ, তালিকা () এই ক্ষেত্রে ভাল। টি শুধুমাত্র তখনই কার্যকর যদি আপনি পুরো তালিকাটি
মহাকর্ষ

148

জেনারেটরগুলি পুনরায় চালু করা যায় না। আপনার নিম্নলিখিত বিকল্পগুলি রয়েছে:

  1. জেনারেটর ফাংশনটি আবার চালান, প্রজন্মটি পুনরায় চালু করুন:

    y = FunctionWithYield()
    for x in y: print(x)
    y = FunctionWithYield()
    for x in y: print(x)
  2. জেনারেটরের ফলাফলগুলিকে মেমরি বা ডিস্কে কোনও ডেটা স্ট্রাকচারে সঞ্চয় করুন যা আপনি আবার পুনরুক্ত করতে পারবেন:

    y = list(FunctionWithYield())
    for x in y: print(x)
    # can iterate again:
    for x in y: print(x)

বিকল্প 1 এর নেতিবাচক দিকটি হ'ল এটি আবার মানগুলি গণনা করে। যদি এটি সিপিইউ-নিবিড় হয় তবে আপনি দুবার গণনা শেষ করবেন। অন্যদিকে, 2 এর ডাউনসাইড হ'ল স্টোরেজ। মানগুলির সম্পূর্ণ তালিকা মেমোরিতে সংরক্ষণ করা হবে। যদি অনেকগুলি মান থাকে তবে তা অনুচ্চারিত হতে পারে।

সুতরাং আপনার কাছে ক্লাসিক মেমরি বনাম প্রসেসিং ট্রেড অফ রয়েছে । আমি জেনারেটরটিকে রিয়েলাইন্ড করার কোনও উপায় কল্পনাও করতে পারি না হয় মানগুলি সংরক্ষণ না করে বা সেগুলি আবার গণনা করা ছাড়া।


ফাংশন কলের স্বাক্ষর সংরক্ষণের কোনও উপায় থাকতে পারে? ফাংশনউইথইয়েল্ড, প্যারাম 1, প্যারাম 2 ...
বুক করুন

3
@ ডিউফাই: নিশ্চিত: ডিএফ কল_মাই_ফুঙ্ক (): ফাংশন উইথইয়েল্ড (প্যারাম 1, প্যারাম 2)
রিটার্ন করুন

@ দেউফাই "ফাংশন কলের স্বাক্ষর সংরক্ষণ করুন" বলতে কী বোঝ? আপনি দয়া করে ব্যাখ্যা করতে পারেন? আপনি কি জেনারেটরের কাছে দেওয়া প্যারামিটারগুলি সংরক্ষণ করছেন?
Беньковский

2
(1) এর আরেকটি নেতিবাচকতা হ'ল ফাংশনউইথইয়েল্ড () কেবল ব্যয়বহুল নয়, তবে পুনরায় গণনা করাও অসম্ভব , যেমন যদি এটি স্টিডিনের কাছ থেকে পড়া হয়।
সর্বাধিক

2
@ ম্যাক্স যা বলেছিল তা প্রতিধ্বনিত করতে, যদি ফাংশনের আউটপুট কলগুলির মধ্যে পরিবর্তিত হতে পারে (বা হবে), (1) অপ্রত্যাশিত এবং / বা অনাকাঙ্ক্ষিত ফলাফল দিতে পারে।
স্যাম_বাটার

36
>>> def gen():
...     def init():
...         return 0
...     i = init()
...     while True:
...         val = (yield i)
...         if val=='restart':
...             i = init()
...         else:
...             i += 1

>>> g = gen()
>>> g.next()
0
>>> g.next()
1
>>> g.next()
2
>>> g.next()
3
>>> g.send('restart')
0
>>> g.next()
1
>>> g.next()
2

29

সম্ভবত সবচেয়ে সহজ সমাধান হ'ল কোনও জিনিসের ব্যয়বহুল অংশটি মোড়ানো এবং এটি জেনারেটরের কাছে পৌঁছে দেওয়া:

data = ExpensiveSetup()
for x in FunctionWithYield(data): pass
for x in FunctionWithYield(data): pass

এইভাবে, আপনি ব্যয়বহুল গণনাগুলি ক্যাশে করতে পারেন।

আপনি যদি একই সাথে সমস্ত ফলাফল র‍্যামে রাখতে পারেন list()তবে জেনারেটরের ফলাফলগুলি সরল তালিকায় কার্যকর করতে ব্যবহার করুন এবং এটির সাথে কাজ করুন।


23

আমি পুরানো সমস্যার আলাদা সমাধান দিতে চাই

class IterableAdapter:
    def __init__(self, iterator_factory):
        self.iterator_factory = iterator_factory

    def __iter__(self):
        return self.iterator_factory()

squares = IterableAdapter(lambda: (x * x for x in range(5)))

for x in squares: print(x)
for x in squares: print(x)

এর মতো কোনও কিছুর সাথে তুলনা করার সময় এর সুবিধাটি list(iterator)হ'ল এটি O(1)স্থান জটিলতা এবং list(iterator)তা O(n)। অসুবিধাটি হ'ল, যদি আপনার কেবলমাত্র পুনরাবৃত্তির অ্যাক্সেস থাকে তবে পুনরুক্তি উত্পাদনকারী ফাংশনটি না থাকলে আপনি এই পদ্ধতিটি ব্যবহার করতে পারবেন না। উদাহরণস্বরূপ, নিম্নলিখিতগুলি করা যুক্তিসঙ্গত বলে মনে হতে পারে তবে এটি কার্যকর হবে না।

g = (x * x for x in range(5))

squares = IterableAdapter(lambda: g)

for x in squares: print(x)
for x in squares: print(x)

@ ডেভিফাই প্রথম স্নিপেটে, জেনারেটরটি "স্কোয়ারস = ..." লাইনে রয়েছে। জেনারেটর এক্সপ্রেশন ফলন ব্যবহার করে এমন একটি ফাংশন কল করার মতোই আচরণ করে এবং আমি কেবলমাত্র এটি ব্যবহার করি কারণ এটি একটি সংক্ষিপ্ত উদাহরণের জন্য ফলন সহ একটি ফাংশন লেখার চেয়ে কম ভার্বোস। দ্বিতীয় স্নিপেটে, আমি জেনারেটর_ফ্যাক্টরি হিসাবে ফাংশনউইথইয়েল্ড ব্যবহার করেছি, সুতরাং যখনই এটির ডাকা হবে তখনই এটি ডাকা হবে, যখনই আমি "এক্স ইন ওয়াইয়ের জন্য" লিখি।
মাইকেলসনোদ্দিন

ভাল সমাধান। এটি আসলে রাষ্ট্রীয় পুনরাবৃত্তকারী বস্তুর পরিবর্তে একটি রাষ্ট্রবিহীন পুনরাবৃত্তযোগ্য অবজেক্ট তৈরি করে, সুতরাং বস্তুটি নিজেই পুনরায় ব্যবহারযোগ্য। বিশেষত কার্যকর যদি আপনি কোনও ফাংশনে পুনরাবৃত্তিযোগ্য অবজেক্টটি পাস করতে চান এবং সেই ফাংশনটি অবজেক্টটিকে একাধিকবার ব্যবহার করবে।
Cosyn

5

যদি গ্রজেগোর্জে ওলেডজকির উত্তরটি যথেষ্ট না হয় তবে আপনি সম্ভবত send()আপনার লক্ষ্য অর্জনে ব্যবহার করতে পারেন। বর্ধিত জেনারেটর এবং ফলন প্রকাশের বিষয়ে আরও তথ্যের জন্য PEP-0342 দেখুন ।

আপডেট: এছাড়াও দেখুন itertools.tee()। এটিতে উল্লিখিত সেই স্মৃতি বনাম প্রক্রিয়াকরণ ট্রেড অফের কয়েকটি জড়িত রয়েছে, তবে এটি জেনারেটরের ফলাফলগুলিকে কেবল স্টোর করে কিছু মেমরি সঞ্চয় করতে পারেlist ; এটি নির্ভর করে আপনি কীভাবে জেনারেটরটি ব্যবহার করছেন।


5

যদি আপনার জেনারেটর এমন এক অর্থে খাঁটি হয় যে এর আউটপুটটি কেবলমাত্র পাস হওয়া যুক্তি এবং ধাপ সংখ্যার উপর নির্ভর করে এবং আপনি ফলস্বরূপ জেনারেটরটি পুনরায় আরম্ভ হতে চান তবে এখানে একটি সাজানোর স্নিপেটটি কার্যকর হতে পারে:

import copy

def generator(i):
    yield from range(i)

g = generator(10)
print(list(g))
print(list(g))

class GeneratorRestartHandler(object):
    def __init__(self, gen_func, argv, kwargv):
        self.gen_func = gen_func
        self.argv = copy.copy(argv)
        self.kwargv = copy.copy(kwargv)
        self.local_copy = iter(self)

    def __iter__(self):
        return self.gen_func(*self.argv, **self.kwargv)

    def __next__(self):
        return next(self.local_copy)

def restartable(g_func: callable) -> callable:
    def tmp(*argv, **kwargv):
        return GeneratorRestartHandler(g_func, argv, kwargv)

    return tmp

@restartable
def generator2(i):
    yield from range(i)

g = generator2(10)
print(next(g))
print(list(g))
print(list(g))
print(next(g))

আউটপুট:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[]
0
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1

3

টিয়ের সরকারী নথি থেকে :

সাধারণভাবে, যদি কোনও পুনরাবৃত্তকারী অন্য পুনরুক্তি শুরু হওয়ার আগে যদি বেশিরভাগ বা সমস্ত ডেটা ব্যবহার করে তবে টি () এর পরিবর্তে তালিকা () ব্যবহার করা আরও দ্রুত।

সুতরাং list(iterable)আপনার ক্ষেত্রে পরিবর্তে এটি ব্যবহার করা ভাল ।


6
অসীম জেনারেটর সম্পর্কে কি?
ডিউফাই

1
গতি একমাত্র বিবেচনা নয়; list()পুরো পুনরাবৃত্তিকে স্মৃতিতে রাখে
ক্রিস_র্যান্ডস

@ ক্রিস_আর্যান্ডস তাই tee()যদি একজন পুনরাবৃত্তিকারী সমস্ত মান ব্যবহার করে - তবে এটি কার্যকরভাবে teeকাজ করে।
এচাম্পিয়ন

2
@ ডিউফাই: অসীম জেনারেটরের জন্য, অ্যারোন ডিগুল্লার সমাধান ব্যবহার করুন (মূল্যবান ডেটা ফিরিয়ে দেওয়া এক্সপ্রেসিটিসআপ ফাংশন))
জেফ লারম্যান

3

পরিচালনা করার জন্য একটি মোড়ক ফাংশন ব্যবহার করে StopIteration

আপনি আপনার জেনারেটর-উত্পাদনকারী ফাংশনে একটি সাধারণ মোড়ক ফাংশন লিখতে পারেন যা জেনারেটর শেষ হয়ে গেলে ট্র্যাক করে। StopIterationএটি পুনরুক্তির শেষে পৌঁছলে কোনও জেনারেটর নিক্ষেপ করে ব্যতিক্রম ব্যবহার করে এটি করবে ।

import types

def generator_wrapper(function=None, **kwargs):
    assert function is not None, "Please supply a function"
    def inner_func(function=function, **kwargs):
        generator = function(**kwargs)
        assert isinstance(generator, types.GeneratorType), "Invalid function"
        try:
            yield next(generator)
        except StopIteration:
            generator = function(**kwargs)
            yield next(generator)
    return inner_func

আপনি উপরে স্পট করতে পারেন, যখন আমাদের মোড়ক ফাংশন একটি StopIterationব্যতিক্রম ধরা পড়ে , এটি কেবল জেনারেটর অবজেক্টটিকে পুনরায় আরম্ভ করে (ফাংশন কলের অন্য একটি উদাহরণ ব্যবহার করে)।

এবং তারপরে, ধরে নিলাম যে আপনি আপনার জেনারেটর সরবরাহকারী ক্রিয়াকলাপটি নীচের মতো কোথাও সংজ্ঞায়িত করেছেন, আপনি পাইথন ফাংশন ডেকোরেটর সিনট্যাক্সটি এটিকে স্পষ্টভাবে গুটিয়ে রাখতে ব্যবহার করতে পারেন:

@generator_wrapper
def generator_generating_function(**kwargs):
    for item in ["a value", "another value"]
        yield item

2

আপনি কোনও ফাংশন সংজ্ঞায়িত করতে পারেন যা আপনার জেনারেটরকে ফেরত দেয়

def f():
  def FunctionWithYield(generator_args):
    code here...

  return FunctionWithYield

এখন আপনি নিজের পছন্দ অনুযায়ী যতবার করতে পারেন:

for x in f()(generator_args): print(x)
for x in f()(generator_args): print(x)

1
উত্তরের জন্য আপনাকে ধন্যবাদ, তবে প্রশ্নের মূল বিষয়টি সৃষ্টি এড়ানো ছিল , অভ্যন্তরীণ ফাংশনকে
সঞ্চারিত

1

আপনি ব্যয়বহুল প্রস্তুতি বলতে কী বোঝাতে চেয়েছিলেন তা আমি নিশ্চিত নই, তবে আমি অনুমান করি যে আপনার আসলে কী আছে

data = ... # Expensive computation
y = FunctionWithYield(data)
for x in y: print(x)
#here must be something to reset 'y'
# this is expensive - data = ... # Expensive computation
# y = FunctionWithYield(data)
for x in y: print(x)

যদি তা হয় তবে কেন পুনরায় ব্যবহার dataকরবেন না ?


1

পুনরুদ্ধারকারীদের পুনরায় সেট করার কোনও বিকল্প নেই। next()ফাংশনটির মাধ্যমে পুনরাবৃত্তি হওয়ার সময় সাধারণত আইট্রেটার পপ আউট হয়। একমাত্র উপায় হ'ল পুনরাবৃত্তকারী অবজেক্টটিতে পুনরাবৃত্ত হওয়ার আগে একটি ব্যাকআপ নেওয়া। নীচে চেক করুন।

0 থেকে 9 আইটেমগুলির সাথে পুনরাবৃত্তকারী অবজেক্ট তৈরি করা হচ্ছে

i=iter(range(10))

পরবর্তী () ফাংশনটির মাধ্যমে আইট্রেট করা যা পপ আউট হবে

print(next(i))

পুনরাবৃত্তকারী অবজেক্টকে তালিকায় রূপান্তর করা

L=list(i)
print(L)
output: [1, 2, 3, 4, 5, 6, 7, 8, 9]

সুতরাং আইটেম 0 ইতিমধ্যে পপ আউট হয়েছে। আমরা পুনরাবৃত্তিকে তালিকায় রূপান্তর করায় সমস্ত আইটেম পপ করা হয়।

next(L) 

Traceback (most recent call last):
  File "<pyshell#129>", line 1, in <module>
    next(L)
StopIteration

সুতরাং পুনরাবৃত্তি শুরু করার আগে আপনাকে ব্যাকআপের জন্য তালিকায় পুনরাবৃত্তিকে রূপান্তর করতে হবে। তালিকার সাথে পুনরাবৃত্তিতে রূপান্তর করা যেতে পারেiter(<list-object>)


1

আপনি এখন more_itertools.seekable(একটি তৃতীয় পক্ষের সরঞ্জাম) ব্যবহার করতে পারেন যা পুনরায় সেট করা পুনরাবৃত্তি সক্ষম করে।

এর মাধ্যমে ইনস্টল করুন > pip install more_itertools

import more_itertools as mit


y = mit.seekable(FunctionWithYield())
for x in y:
    print(x)

y.seek(0)                                              # reset iterator
for x in y:
    print(x)

দ্রষ্টব্য: পুনরুক্তি করার সময় মেমরির খরচ বেড়ে যায়, তাই বড় পুনরাবৃত্তি থেকে সাবধান থাকুন।


1

আপনি এটি করতে পারবেন itertools.cycle () ব্যবহার করে আপনি এই পদ্ধতিটির সাহায্যে একটি পুনরুক্তি তৈরি করতে পারেন এবং তারপরে পুনরুক্তিটির উপর একটি লুপ প্রয়োগ করতে পারেন যা এর মানগুলি লুপ করবে will

উদাহরণ স্বরূপ:

def generator():
for j in cycle([i for i in range(5)]):
    yield j

gen = generator()
for i in range(20):
    print(next(gen))

20 টি সংখ্যা, 0 থেকে 4 বার বার উত্পন্ন করবে।

দস্তাবেজগুলির একটি নোট:

Note, this member of the toolkit may require significant auxiliary storage (depending on the length of the iterable).

+1 কারণ এটি কাজ করে তবে আমি সেখানে 2 টি সমস্যা দেখছি 1) বড় মেমরির পদচিহ্ন যেহেতু ডকুমেন্টেশনে বলা হয়েছে "একটি অনুলিপি তৈরি করুন" 2) অসীম লুপ অবশ্যই যা চাই তা নয়
ডিউফাই

0

ঠিক আছে, আপনি বলেছিলেন যে আপনি একাধিকবার একটি জেনারেটর কল করতে চান, তবে আরম্ভটি ব্যয়বহুল ... এরকম কিছু কী?

class InitializedFunctionWithYield(object):
    def __init__(self):
        # do expensive initialization
        self.start = 5

    def __call__(self, *args, **kwargs):
        # do cheap iteration
        for i in xrange(5):
            yield self.start + i

y = InitializedFunctionWithYield()

for x in y():
    print x

for x in y():
    print x

বিকল্পভাবে, আপনি কেবল নিজের ক্লাস তৈরি করতে পারেন যা পুনরায় প্রোটোকল অনুসরণ করে এবং কিছু ধরণের 'রিসেট' ফাংশন সংজ্ঞায়িত করে।

class MyIterator(object):
    def __init__(self):
        self.reset()

    def reset(self):
        self.i = 5

    def __iter__(self):
        return self

    def next(self):
        i = self.i
        if i > 0:
            self.i -= 1
            return i
        else:
            raise StopIteration()

my_iterator = MyIterator()

for x in my_iterator:
    print x

print 'resetting...'
my_iterator.reset()

for x in my_iterator:
    print x

https://docs.python.org/2/library/stdtyype.html#iterator-typs http://anandology.com/python-pੈਕਟ-book/iterators.html


আপনি কেবল মোড়কে সমস্যা ডেকে আনুন। ধরে নিন যে ব্যয়বহুল সূচনা জেনারেটর তৈরি করে। আমার প্রশ্নটি কীভাবে আপনার অভ্যন্তরে পুনরায় সেট করবেন সে সম্পর্কে ছিল__call__
দেউফাই

আপনার মন্তব্যের জবাবে দ্বিতীয় উদাহরণ যুক্ত করা হয়েছে। এটি মূলত একটি রিসেট পদ্ধতি সহ একটি কাস্টম জেনারেটর।
tvt173

0

আমার উত্তরটি কিছুটা আলাদা সমস্যার সমাধান করে: যদি জেনারেটরটি আরম্ভ করার জন্য ব্যয়বহুল হয় এবং প্রতিটি উত্পন্ন জিনিস উত্পন্ন করার জন্য ব্যয়বহুল হয়। তবে একাধিক ফাংশনে আমাদের একাধিকবার জেনারেটর গ্রহণ করতে হবে। জেনারেটর এবং প্রতিটি উত্পন্ন অবজেক্টকে কল করার জন্য আমরা একবার থ্রেড ব্যবহার করতে পারি এবং গ্রাহক পদ্ধতিগুলির প্রতিটি বিভিন্ন থ্রেডে চালাতে পারি। জিআইএল-এর কারণে আমরা সত্যিকারের সমান্তরালতা অর্জন করতে পারি না, তবে আমরা আমাদের লক্ষ্য অর্জন করব।

এই পদ্ধতির নিম্নলিখিত ক্ষেত্রে একটি ভাল কাজ করেছে: গভীর শেখার মডেল অনেকগুলি চিত্র প্রক্রিয়া করে। ফলাফলটি চিত্রটিতে প্রচুর অবজেক্টের জন্য প্রচুর মুখোশ। প্রতিটি মুখোশ স্মৃতি গ্রাস করে। আমাদের প্রায় 10 টি পদ্ধতি রয়েছে যা বিভিন্ন পরিসংখ্যান এবং মেট্রিকগুলি তৈরি করে তবে তারা একবারে সমস্ত চিত্র গ্রহণ করে। সমস্ত চিত্র মেমরির সাথে খাপ খায় না। পুনঃনির্দেশক গ্রহণ করার জন্য মোথডগুলি সহজেই আবার লেখা যেতে পারে।

class GeneratorSplitter:
'''
Split a generator object into multiple generators which will be sincronised. Each call to each of the sub generators will cause only one call in the input generator. This way multiple methods on threads can iterate the input generator , and the generator will cycled only once.
'''

def __init__(self, gen):
    self.gen = gen
    self.consumers: List[GeneratorSplitter.InnerGen] = []
    self.thread: threading.Thread = None
    self.value = None
    self.finished = False
    self.exception = None

def GetConsumer(self):
    # Returns a generator object. 
    cons = self.InnerGen(self)
    self.consumers.append(cons)
    return cons

def _Work(self):
    try:
        for d in self.gen:
            for cons in self.consumers:
                cons.consumed.wait()
                cons.consumed.clear()

            self.value = d

            for cons in self.consumers:
                cons.readyToRead.set()

        for cons in self.consumers:
            cons.consumed.wait()

        self.finished = True

        for cons in self.consumers:
            cons.readyToRead.set()
    except Exception as ex:
        self.exception = ex
        for cons in self.consumers:
            cons.readyToRead.set()

def Start(self):
    self.thread = threading.Thread(target=self._Work)
    self.thread.start()

class InnerGen:
    def __init__(self, parent: "GeneratorSplitter"):
        self.parent: "GeneratorSplitter" = parent
        self.readyToRead: threading.Event = threading.Event()
        self.consumed: threading.Event = threading.Event()
        self.consumed.set()

    def __iter__(self):
        return self

    def __next__(self):
        self.readyToRead.wait()
        self.readyToRead.clear()
        if self.parent.finished:
            raise StopIteration()
        if self.parent.exception:
            raise self.parent.exception
        val = self.parent.value
        self.consumed.set()
        return val

Ussage:

genSplitter = GeneratorSplitter(expensiveGenerator)

metrics={}
executor = ThreadPoolExecutor(max_workers=3)
f1 = executor.submit(mean,genSplitter.GetConsumer())
f2 = executor.submit(max,genSplitter.GetConsumer())
f3 = executor.submit(someFancyMetric,genSplitter.GetConsumer())
genSplitter.Start()

metrics.update(f1.result())
metrics.update(f2.result())
metrics.update(f3.result())

আপনি শুধু নতুন করে itertools.isliceবা ASYNC জন্য aiostream.stream.take, এবং এই পোস্টটি আপনার / অপেক্ষায় রয়েছেন পথ asyn মধ্যে এটা করতে পারেন stackoverflow.com/a/42379188/149818
Dewfy

-3

এটি কোড অবজেক্ট দ্বারা করা যেতে পারে। এখানে উদাহরণ।

code_str="y=(a for a in [1,2,3,4])"
code1=compile(code_str,'<string>','single')
exec(code1)
for i in y: print i

1 2 3 4

for i in y: print i


exec(code1)
for i in y: print i

1 2 3 4


4
ভাল, আসলে জেনারেটর পুনরায় সেট করা আরম্ভের কোডটির দ্বিগুণ প্রয়োগ এড়াতে প্রয়োজন ছিল। আপনার দৃষ্টিভঙ্গি (1) যাইহোক যাইহোক দু'বার সূচনা সম্পাদন করে, (২) এতে জড়িত থাকে execযে এই জাতীয় সরল মামলার জন্য কিছুটা অ-প্রস্তাবিত।
শোধ করুন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.