Pythons itertools
hat tee
für n-plizierende iterables:
Ich konnte das Äquivalent in Boost::Range
nicht finden. Fehle ich etwas oder sollte ich einfach mein eigenes rollen?
itertools.tee eignet sich gut für Single-Pass-Iterables, die allgegenwärtig sind Python. Zum Beispiel Generatoren sind Single-Pass, und sie werden oft verwendet.
Aber wenn Sie bereits eine list / deque haben, werden Sie itertools.tee dafür nicht verwenden, da dies überflüssige Duplizierung bedeuten würde - Sie können einfach immer über die ursprüngliche Liste / Deque iterieren.
C ++ hat auch ein Konzept für Single-Pass-Bereiche, zum Beispiel Input Iterator , aber das ist nicht so allgegenwärtig. Es ist die Konsequenz einer anderen Reihe von Zielen des typischen C ++ - Programms - geben Sie dem Benutzer ein Maximum an Möglichkeiten, um die beste Leistung zu erhalten. Es ist eine andere Einstellung, wenn Sie es wünschen.
Um dies zu veranschaulichen, vergleichen wir boost :: transformed und itertools.imap (oder generatorausdrücke ):
Beide bieten eine Ansicht der Eingangssequenz über ein gegebenes "Prisma". itertools.imap gibt einen einzelnen Durchlauf iterabel zurück, während boost :: transformed Bereichsansicht zurückgibt, die die gleiche Kategorie wie der Eingabebereich hat - dh wenn Sie Random Access Range als Eingabe würden Sie Random Access Range erhalten als Ergebnis.
Eine weitere Tatsache ist, dass C ++ standardmäßig Wertesemantik verwendet, während Python eine Pointer-Semantik hat. Es bedeutet, dass, wenn Iterator in C ++ kopieren, und es mehrere Male "bump" - original Iterator wird nicht geändert (obwohl es ungültig werden kann, wenn es Single-Pass-Bereich ist, aber es ist nicht der Punkt).
Aber manchmal möchten Sie Werte aus einem einzelnen Durchlaufbereich akkumulieren und sie mehrere Male betrachten. In einem solchen Fall besteht die gebräuchlichste Lösung darin, Werte in einem Container explizit mit den Händen zu sammeln. Zum Beispiel:
%Vor%T-artige Wrapper sind in C ++ noch möglich, hier ist Proof-of-Concept . Verwendung ist:
%Vor%tee_range nimmt single pass range als Argument und gibt forward range zurück (das ist Multi-Pass) (es gibt auch make_tee_iterator , das auf Iteratorebene funktioniert). Sie können also Kopien dieses Bereichs erstellen und mehrmals wiederholen:
%Vor%Es gibt auch eine Verbesserung gegenüber itertools.tee - intern wird nur ein deque zum Zwischenspeichern von Werten verwendet.
%Vor%Ausgabe ist:
%Vor%Boost.Spirit hat Multipass-Iterator mit ähnlichen Zielen.
Der multi_pass-Iterator konvertiert jeden Eingabe-Iterator in einen Vorwärts-Iterator, der für die Verwendung mit Spirit.Qi geeignet ist. multi_pass puffert Daten bei Bedarf und verwirft den Puffer, wenn sein Inhalt nicht mehr benötigt wird. Dies geschieht entweder, wenn nur eine Kopie des Iterators existiert oder wenn kein Backtracking auftreten kann.
Tags und Links c++ boost boost-range