222 Stimmen

Anzahl der Elemente in einem Iterator in Python ermitteln

Gibt es einen effizienten Weg, um zu wissen, wie viele Elemente in einem Iterator in Python, im Allgemeinen, ohne Iteration durch jedes und Zählen sind?

0 Stimmen

0voto

tom10 Punkte 63374

Es ist gängige Praxis, diese Art von Informationen in den Dateikopf zu stellen, und pysam gibt Ihnen Zugriff darauf. Ich kenne das Format nicht, aber haben Sie die API überprüft?

Wie andere bereits gesagt haben, kann man die Länge nicht aus dem Iterator ablesen.

-2voto

Toothpick Anemone Punkte 2267

Vermutlich wollen Sie die Anzahl der Elemente zählen, ohne zu iterieren, so dass der Iterator nicht erschöpft ist und Sie ihn später wieder verwenden können. Dies ist möglich mit copy o deepcopy

import copy

def get_iter_len(iterator):
    return sum(1 for _ in copy.copy(iterator))

###############################################

iterator = range(0, 10)
print(get_iter_len(iterator))

if len(tuple(iterator)) > 1:
    print("Finding the length did not exhaust the iterator!")
else:
    print("oh no! it's all gone")

Die Ausgabe lautet " Finding the length did not exhaust the iterator! "

Optional (und nicht ratsam) können Sie die integrierte len wie folgt funktionieren:

import copy

def len(obj, *, len=len):
    try:
        if hasattr(obj, "__len__"):
            r = len(obj)
        elif hasattr(obj, "__next__"):
            r = sum(1 for _ in copy.copy(obj))
        else:
            r = len(obj)
    finally:
        pass
    return r

2 Stimmen

Ranges sind keine Iteratoren. Es gibt einige Iterator-Typen, die kopiert werden können, aber andere führen dazu, dass dieser Code mit einem TypeError fehlschlägt (z.B. Generatoren), und die Iteration durch einen kopierten Iterator kann dazu führen, dass Seiteneffekte zweimal auftreten, oder einen willkürlichen Bruch im Code verursachen, der beispielsweise einen map Iterator in der Erwartung, dass die resultierenden Funktionsaufrufe nur einmal erfolgen.

-2voto

hasen Punkte 154413
def count_iter(iter):
    sum = 0
    for _ in iter: sum += 1
    return sum

0 Stimmen

In der Frage wurde ausdrücklich darauf hingewiesen, dass die Iteration keine gültige Option ist. Dies führt auch bei unendlichen Generatoren zu einer Endlosschleife.

-2voto

Gulzar Punkte 16632

Dies ist theoretisch unmöglich: Dies ist in der Tat die Halteproblem .

Proof

Angenommen, es wäre möglich, die Länge (oder unendliche Länge) eines beliebigen Generators zu bestimmen g mit Hilfe einer Funktion len(g) .

Für jedes Programm P lassen Sie uns nun umrechnen P in einen Generator g(P) : Für jeden Rückgabe- oder Ausspeisepunkt in P einen Wert liefern, anstatt ihn zurückzugeben.

Si len(g(P)) == infinity P hört nicht auf.

Damit wird das Halting-Problem gelöst, das bekanntermaßen unmöglich ist, siehe Wikipedia . Widersprüche.


Es ist also nicht möglich, die Elemente eines generischen Generators zu zählen, ohne ihn zu iterieren (==das Programm tatsächlich durchlaufen zu lassen).

Konkreter betrachtet

def g():
    while True:
        yield "more?"

Die Länge ist unendlich. Es gibt unendlich viele solcher Generatoren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X