time_interval = [4, 6, 12]
Ich möchte die Zahlen wie [4, 4+6, 4+6+12]
folgt zusammenfassen, um die Liste zu erhalten t = [4, 10, 22]
.
Ich habe folgendes versucht:
t1 = time_interval[0]
t2 = time_interval[1] + t1
t3 = time_interval[2] + t2
print(t1, t2, t3) # -> 4 10 22
python
list
sum
accumulate
user2259323
quelle
quelle
Antworten:
Wenn Sie mit solchen Arrays viel numerische Arbeit leisten, würde ich vorschlagen
numpy
, dass sie eine kumulative Summenfunktion enthaltencumsum
:Numpy ist für solche Dinge oft schneller als reines Python, siehe im Vergleich zu @ Ashwinis
accumu
:Aber wenn es der einzige Ort ist, an dem Sie Numpy verwenden, lohnt es sich möglicherweise nicht, davon abhängig zu sein.
quelle
np.cumsun
Fall haben, der mit einer Liste beginnt, um die Konvertierungszeit zu berücksichtigen.list
würde ich nicht empfehlennumpy
.timeit
, „wenn-n
nicht angegeben ist, eine geeignete Anzahl von Schleifen ist , indem man versucht , aufeinanderfolgende Potenzen von 10 , bis der Gesamtzeit berechnet beträgt mindestens 0,2 Sekunden.“ Wenn Sie erwarten, dass es einen Unterschied macht, können Sie liefern-n 1000
, um alle gleichwertig zu machen.In Python 2 können Sie Ihre eigene Generatorfunktion folgendermaßen definieren:
Und in Python 3.2+ können Sie Folgendes verwenden
itertools.accumulate()
:quelle
total = 0; partial_sums = [total := total + v for v in values]
. Ich würde immer noch erwartenaccumulate
, schneller zu sein.Erblicken:
Wird ausgegeben (wie erwartet):
quelle
c + [c[-1] + x]
summieren sich zu einer quadratischen Gesamtlaufzeit in der Eingabelänge.Ich habe mit Python 3.4 einen Benchmark der beiden besten Antworten durchgeführt und festgestellt, dass dies
itertools.accumulate
schneller ist alsnumpy.cumsum
unter vielen Umständen, oft viel schneller. Wie Sie den Kommentaren entnehmen können, ist dies jedoch möglicherweise nicht immer der Fall, und es ist schwierig, alle Optionen ausführlich zu untersuchen. (Fühlen Sie sich frei, einen Kommentar hinzuzufügen oder diesen Beitrag zu bearbeiten, wenn Sie weitere interessante Benchmark-Ergebnisse haben.)Einige Timings ...
Für kurze Listen
accumulate
ist etwa 4 mal schneller:Bei längeren Listen
accumulate
geht das ca. 3 mal schneller:Wenn das
numpy
array
nicht gegossen wirdlist
,accumulate
ist es immer noch ungefähr 2 mal schneller:Wenn Sie die Importe außerhalb der beiden Funktionen platzieren und dennoch a zurückgeben
numpy
array
,accumulate
ist dies immer noch fast zweimal schneller:quelle
list
von fünf Artikeln zu verarbeiten, insbesondere wenn Sie nicht bereit sind, einen Gegenwert anzunehmenarray
. Wenn die fragliche Liste wirklich so kurz ist, spielt ihre Laufzeit keine Rolle - Abhängigkeiten und Lesbarkeit würden sicherlich dominieren. Eine weite Verwendung eineslist
einheitlichen numerischen Datentyps von signifikanter Länge wäre jedoch dumm; dafürarray
wäre eine numpy angebracht und normalerweise schneller.numpy
es unter keinen Umständen schneller, wenn ich etwas übersehen habe?sum2
Funktion wird wahrscheinlichl
in ein Array konvertiert . Versuchen Sie das Timinga = np.array(l)
undnp.cumsum(a)
separat. Dann versuchena = np.tile(np.arange(1, 6), 1000)
vsl = [1,2,3,4,5]*1000
. In einem Programm, das andere numerische Prozesse ausführt (wie dasl
erstmalige Erstellen oder Laden ), befinden sich Ihre Arbeitsdaten wahrscheinlich bereits in einem Array, und die Erstellung ist mit konstanten Kosten verbunden.Versuchen Sie Folgendes: Die Akkumulationsfunktion führt zusammen mit dem Operator add die laufende Addition durch.
quelle
operator.add
da die Standardoperation ohnehin das Hinzufügen ist.Zuweisungsausdrücke aus PEP 572 (neu in Python 3.8) bieten eine weitere Möglichkeit, dies zu lösen:
quelle
Sie können die kumulative Summenliste in linearer Zeit mit einer einfachen
for
Schleife berechnen :Die Standardbibliotheken sind
itertools.accumulate
möglicherweise eine schnellere Alternative (da sie in C implementiert sind):quelle
Das Ausführen dieses Codes gibt
quelle
In Python3 können Sie Folgendes tun, um die kumulative Summe einer Liste zu ermitteln, wobei das
i
th-Element die Summe der ersten i + 1-Elemente aus der ursprünglichen Liste ist:ODER Sie können das Listenverständnis verwenden:
Ausgabe
quelle
Wenn Sie eine pythonische Methode ohne Numpy in 2.7 verwenden möchten, ist dies meine Vorgehensweise
Probieren wir es jetzt aus und testen es gegen alle anderen Implementierungen
quelle
Zunächst möchten Sie eine laufende Liste von Teilsequenzen:
Dann rufen Sie einfach
sum
jede Teilsequenz auf:(Dies ist nicht die effizienteste Methode, da Sie alle Präfixe wiederholt hinzufügen. In den meisten Anwendungsfällen spielt dies jedoch wahrscheinlich keine Rolle, und es ist einfacher zu verstehen, wenn Sie nicht daran denken müssen die laufenden Summen.)
Wenn Sie Python 3.2 oder höher verwenden, können Sie
itertools.accumulate
dies für Sie tun:Und wenn Sie 3.1 oder früher verwenden, können Sie einfach kopieren Sie die „gleichbedeutend mit“ Quelle direkt aus der Dokumentation ( mit Ausnahme des Wechsels
next(it)
aufit.next()
2,5 und früher).quelle
range
als[1:]
am Ende[4,6,12]
da er, wie er in der Frage schrieb, bereits weiß, was das ist!Versuche dies:
quelle
Abhängig von der Länge der Liste und der Leistung kann es viele Antworten geben. Ein sehr einfacher Weg, den ich denken kann, ohne an die Aufführung zu denken, ist folgender:
[1, 3, 6, 10]
Dies geschieht durch Verwendung des Listenverständnisses und dies kann ziemlich gut funktionieren. Es ist nur so, dass ich hier viele Male über das Subarray hinzufüge. Sie könnten möglicherweise improvisieren und es einfach machen!
Prost auf dein Bestreben!
quelle
Dies ist etwas schneller als die oben beschriebene Generatormethode von @Ashwini für kleine Listen
Bei größeren Listen ist der Generator der richtige Weg. . .
quelle
Etwas hackig, scheint aber zu funktionieren:
Ich dachte, dass die innere Funktion in der Lage sein würde, das
y
im äußeren lexikalischen Bereich deklarierte zu ändern , aber das hat nicht funktioniert, also spielen wir stattdessen einige böse Hacks mit Strukturmodifikation. Es ist wahrscheinlich eleganter, einen Generator zu verwenden.quelle
Ohne Numpy verwenden zu müssen, können Sie direkt über das Array schleifen und die Summe auf dem Weg akkumulieren. Beispielsweise:
Ergebnisse in:
quelle
Ein reiner Python-Oneliner für die kumulative Summe:
Dies ist eine rekursive Version, die von rekursiven kumulativen Summen inspiriert ist . Einige Erklärungen:
X[:1]
ist eine Liste, die das vorherige Element enthält und fast identisch mit[X[0]]
(was sich für leere Listen beschweren würde).cumsum
Aufruf im zweiten Term verarbeitet das aktuelle Element[1]
und die verbleibende Liste, deren Länge um eins reduziert wird.if X[1:]
ist kürzer fürif len(X)>1
.Prüfung:
Und ähnlich für kumulatives Produkt:
Prüfung:
quelle
quelle
Hier ist eine weitere unterhaltsame Lösung. Dies nutzt das
locals()
Diktat eines Verständnisses aus, dh lokale Variablen, die innerhalb des Bereichs des Listenverständnisses erzeugt werden:So
locals()
sieht das für jede Iteration aus:Die Leistung ist für kleine Listen nicht schlecht:
Und fällt offensichtlich für größere Listen flach.
Obwohl die Methode hässlich und nicht praktisch ist, macht sie auf jeden Fall Spaß.
quelle
Wenn Sie nach einer effizienteren Lösung suchen (größere Listen?), Könnte ein Generator ein guter Anruf sein (oder nur verwenden,
numpy
wenn Sie sich wirklich für Perf interessieren).quelle
Dies wäre im Haskell-Stil:
quelle