Seite 1 von 1

Iterator in Blocks von mehreren items abfragen

Verfasst: Freitag 10. Januar 2020, 10:22
von Mick
Hallo Leute,
vielen Dank für die Hilfe die letzten Tage. Ich hab leider schon wieder eine Frage.

Ich möchte einen Iterator in Blocks von mehreren items abfragen (z.B. 10000 items auf einmal). Der iterator ist sehr lang (mehrere Millionen items) und ich möchte die Blocks dann in einer Funktion bearbeiten und diese an den ProcessPoolExecutor weitergeben, um den Ablauf schneller zu machen.

Ich habe das ganze bisher als Verschachtelung von 3 loops gelöst: Außen eine while-loop, die bis zum Ende des iterators True bleibt, in der Mitte eine Loop für die Anzahl der parallelen Prozesse, die gestartet werden sollen und innen noch eine Loop für die Anzahl an items pro Prozess.

Code: Alles auswählen

iterator = iter(range(100))

bool_more_input = True

while bool_more_input:
	items_for_process = [[] for _ in range(4)] #Liste leeren
	for i in range(4): #Anzahl der Prozesse
		k=0
		while k < 10 and bool_more_input: #Anzahl items pro Prozess
			try:
				item = next(iterator)
				items_for_process[i].append(item)
				k += 1
			except StopIteration:
				bool_more_input = False

	print('Give items to ProcessPoolExecutor:')
	print(items_for_process)
Ich überlege, ob man das ganze irgendwie schöner lösen kann. Ich komme aber nicht drauf. Ich habe mit itertools.islice() herumprobiert, aber dann habe ich keine Rückmeldung mehr wann der iterator leer ist.

Re: Iterator in Blocks von mehreren items abfragen

Verfasst: Freitag 10. Januar 2020, 10:46
von Sirius3
Naja, der Iterator ist fertig, wenn die Liste leer bleibt:

Code: Alles auswählen

while True:
    items_for_process = [list(islice(iterator, 1000)) for _ in range(4)]
    if not any(items_for_process):
        break
    print(items_for_process)

Re: Iterator in Blocks von mehreren items abfragen

Verfasst: Freitag 10. Januar 2020, 11:32
von __blackjack__
@Mick: So ein Executor hat eine `map()`-Methode und die hat ein `chunksize`-Argument. Ansonsten würde ich auch immer erst mal ins `more_itertools`-Modul schauen bevor ich etwas mit Iteratoren selbst erfinde.

Re: Iterator in Blocks von mehreren items abfragen

Verfasst: Freitag 10. Januar 2020, 23:32
von Mick
Sirius3 hat geschrieben: Freitag 10. Januar 2020, 10:46 Naja, der Iterator ist fertig, wenn die Liste leer bleibt:

Code: Alles auswählen

while True:
    items_for_process = [list(islice(iterator, 1000)) for _ in range(4)]
    if not any(items_for_process):
        break
    print(items_for_process)
Perfekt. Das ist viel schöner :)

more_itertools hab ich mir auch nochmal angeguckt und die haben tatsächlich "more_itertools.chunked(iterable, n)", um genau dieses Problem zu lösen. Danke euch!