Wie kann man alle bis auf das letzte Element einer Liste durchlaufen?

160

Ich möchte eine Liste durchlaufen, in der jedes Element mit dem darauf folgenden verglichen wird.

Gibt es eine Möglichkeit, mit x in y alle Elemente außer dem letzten zu durchlaufen? Ich würde es vorziehen, ohne Indizes zu verwenden, wenn ich kann.

Hinweis

freespace beantwortete meine eigentliche Frage, weshalb ich die Antwort akzeptierte, aber SilentGhost beantwortete die Frage, die ich hätte stellen sollen.

Entschuldigung für die Verwirrung.

David Sykes
quelle

Antworten:

315
for x in y[:-1]

Wenn yes sich um einen Generator handelt, funktioniert das oben genannte nicht.

Freiraum
quelle
Das beantwortet meine Frage, danke, aber ich habe vergessen zu fragen, wie ich den Artikel nach x bekommen würde. Ist das möglich?
David Sykes
3
- 1 Ich glaube nicht, dass das die Frage beantwortet. Es wird nicht jedes Element mit dem nächsten verglichen. - Odwl vor 0 Sekunden
Odwl
4
Ich glaube das habe ich getan. Der Autor sagte, er würde gerne X machen und fragte dann, wie er Y machen kann. Ich antwortete, wie er Y machen kann. Dass er meine Antwort akzeptierte, würde bedeuten, dass ich die von ihm gestellte Frage beantwortete, wenn nicht die Frage, die er wirklich stellen wollte. Asker kann diese Antwort gerne herabstufen.
Freiraum
7
Nur weil das OP im ersten eine andere Frage hätte stellen sollen, heißt das nicht, dass seine Frage und diese Antwort für andere nicht sehr nützlich sind. +1
Prof. Falken
1
Sie erwähnen, dass dies bei Generatoren nicht funktioniert. Was ist die Alternative, wenn yein Generator ist?
Joost
50

Der einfachste Weg, das Sequenzelement mit dem folgenden zu vergleichen:

for i, j in zip(a, a[1:]):
     # compare i (the current) to j (the following)
SilentGhost
quelle
15
Dies beantwortet die Frage, die ich gerne gestellt hätte. Danke
David Sykes
3
Tatsächlich können Sie das erste Slice weglassen, da zip die längere Liste auf die Länge des kürzeren abschneidet. Dadurch sparen Sie eine Listenerstellung. (Nur für den Fall, dass Sie es mit riesigen Listen zu tun haben. Aber in diesem Fall sollten Sie dem Ansatz von Ants Aasma folgen, der nichts kopiert.)
Bayer
19

Wenn Sie alle Elemente in der Sequenz paarweise erhalten möchten, verwenden Sie diesen Ansatz (die paarweise Funktion stammt aus den Beispielen im Modul itertools).

from itertools import tee, izip, chain

def pairwise(seq):
    a,b = tee(seq)
    b.next()
    return izip(a,b)

for current_item, next_item in pairwise(y):
    if compare(current_item, next_item):
        # do what you have to do

Wenn Sie den letzten Wert mit einem bestimmten Wert vergleichen müssen, verketten Sie diesen Wert bis zum Ende

for current, next_item in pairwise(chain(y, [None])):
Ameisen Aasma
quelle
Bitte beachten Sie, dass die Verwendung von next für Schatten mit variablem Namen integriert ist
SilentGhost
1
Es macht mir persönlich nichts aus, weniger verwendete Buildins zu beschatten, wenn der Umfang der Variablen klein und der Name gut für die Lesbarkeit ist. Trotzdem wurden die Variablennamen bearbeitet, um gute Codierungspraktiken beizubehalten.
Ants Aasma
5

Wenn Sie das n-te Element mit dem n + 1-ten Element in der Liste vergleichen möchten, können Sie dies auch tun

>>> for i in range(len(list[:-1])):
...     print list[i]>list[i+1]

Beachten Sie, dass dort keine feste Codierung stattfindet. Dies sollte in Ordnung sein, sofern Sie sich nicht anders fühlen.

Perpetualcoder
quelle
3
Sie können len (Liste [: - 1]) durch len (Liste) - 1 ersetzen, um eine Listenkopie zu vermeiden. Und vermeiden Sie die Verwendung einer Variablen namens list ...
Remy Blank
2

So vergleichen Sie jedes Element mit dem nächsten in einem Iterator, ohne eine Liste zu instanziieren:

import itertools
it = (x for x in range(10))
data1, data2 = itertools.tee(it)
data2.next()
for a, b in itertools.izip(data1, data2):
  print a, b
odwl
quelle
2
Genau das wurde von Ants Aasma stackoverflow.com/questions/914715/…
SilentGhost
1

Dies beantwortet, was das OP hätte fragen sollen , dh eine Liste durchlaufen, in der aufeinanderfolgende Elemente verglichen werden (ausgezeichnete SilentGhost- Antwort), die jedoch für jede Gruppe ( n-Gramm ) verallgemeinert ist : 2, 3, ... n:

zip(*(l[start:] for start in range(0, n)))

Beispiele:

l = range(0, 4)  # [0, 1, 2, 3]

list(zip(*(l[start:] for start in range(0, 2)))) # == [(0, 1), (1, 2), (2, 3)]
list(zip(*(l[start:] for start in range(0, 3)))) # == [(0, 1, 2), (1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 4)))) # == [(0, 1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 5)))) # == []

Erklärungen:

  • l[start:] generiert eine Liste / einen Generator ausgehend vom Index start
  • *listoder *generator: Übergibt alle Elemente an die umschließende Funktion, zipals ob sie geschrieben worden wärezip(elem1, elem2, ...)

Hinweis:

AFAIK, dieser Code ist so faul wie möglich. Nicht getestet.

Juanmirocks
quelle