Czy możliwe jest "potokowe" zużycie generatora przez wielu klientów?Potokować iterator dla wielu klientów?
Na przykład często można mieć kod z tego wzoru:
def consumer1(iterator):
for item in iterator:
foo(item)
def consumer2(iterator):
for item in iterator:
bar(item)
myiter = list(big_generator())
v1 = consumer1(myiter)
v2 = consumer2(myiter)
W tym przypadku, wiele funkcji całkowicie zużywa taką samą iterator, co powoduje konieczność buforowania iterator na liście. Ponieważ każdy użytkownik zużywa iterator, itertools.tee
jest bezużyteczny.
Często widzę taki kod i zawsze chciałbym, aby konsumenci mogli konsumować po jednym elemencie, zamiast cachowania całego iteratora. Np .:
consumer1
zużywamyiter[0]
consumer2
zużywamyiter[0]
consumer1
zużywamyiter[1]
consumer2
zużywamyiter[1]
- etc ...
Gdybym MA ke się składni, to będzie wyglądać następująco:
c1_retval, c2_retval = iforkjoin(big_generator(), (consumer1, consumer2))
można zbliżyć się z nici lub multiprzetwarzania i tee
d iteratory, ale nici spożywać przy różnych prędkościach, co oznacza, że wartość deque buforowane wewnątrz tee
może dostać bardzo duże. Nie chodzi tutaj o wykorzystanie równoległości lub przyspieszanie zadań, ale unikanie buforowania dużych sekcji iteratora.
Wydaje mi się, że może to być niemożliwe bez modyfikacji konsumentów, ponieważ kontrola przepływu odbywa się w konsumentach. Jednakże, gdy konsument faktycznie zużywa kontrolę iteracyjną, przechodzi do iteracyjnej metody next()
, więc być może jest możliwe odwrócenie przepływu kontroli w jakiś sposób, tak aby iterator blokował konsumentów po kolei, dopóki nie będzie mógł ich wszystkich podać?
Jeśli to możliwe, nie jestem wystarczająco sprytny, aby zobaczyć, jak. Jakieś pomysły?
Jeśli punkt niekoniecznie jest równoległy, istnieje możliwość scentralizowania iteratora i wysłania danych do każdego * konsumenta *, może przy użyciu klasy z listą 'position% task', która zwraca wartości dla każdego' wydajność ". – Rubens
Może to zrobić za pomocą coroutines? Jeśli masz centralny iterator, który wysyła elementy do pojedynczych użytkowników, możliwe jest uzyskanie tego, co chcesz. W każdym razie myślę, że powinieneś sprawdzić, czy oszczędności pamięci są tak ważne, ponieważ sprawy będą się komplikować. Osobiście po prostu pójdę z 'myiter = list (the_generator())' i przejdę dookoła sekwencji. – Bakuriu