2010-10-03 18 views
10
a = [5, 66, 7, 8, 9, ...] 

Ist es möglich, eine Iteration zu machen, statt so zu schreiben?paarweises Traversieren einer Liste oder eines Tupels

a[1] - a[0] 

a[2] - a[1] 

a[3] - a[2] 

a[4] - a[3] 

...

Vielen Dank!

+4

an welchem ​​Punkt stecken Sie fest? Welchen Code hast du bisher? –

+0

mögliche Duplikate von [Python - Unterschiede zwischen Elementen einer Liste] (http://stackoverflow.com/questions/2400840/python-differences-between-elements-of-a-list) – SilentGhost

Antwort

7

Sicher.

for i in range(1, len(a)): 
    print a[i] - a[i-1] 

Ich sehe nicht, was das eigentliche Problem hier ist. Hast du the python tutorial gelesen?

15

für eine kleine Liste in Python 2 oder jede Liste in Python 3 können Sie

[x - y for x, y in zip(a[1:], a)] 

für eine größere Liste verwenden, werden Sie wahrscheinlich wollen

import itertools as it 

[x - y for x, y in it.izip(a[1:], a)] 

, wenn Sie Python verwenden 2

Und ich würde es als Generator Ausdruck stattdessen

(x - y for x, y in it.izip(a[1:], a)) 
schreiben

Dadurch vermeiden Sie, die zweite Liste im Speicher auf einmal zu erstellen, aber Sie können nur einmal darüber iterieren. Wenn Sie nur einmal durchlaufen möchten, dann ist dies ideal und es ist einfach genug zu ändern, wenn Sie später entscheiden, dass Sie zufälligen oder wiederholten Zugriff benötigen. Insbesondere, wenn Sie es weiter bearbeiten würden, um eine Liste zu erstellen, dann ist diese letzte Option ideal.

Update:

Die schnellste Methode ist bei weitem

import itertools as it 
import operator as op 

list(it.starmap(op.sub, it.izip(a[1:], a))) 

$ python -mtimeit -s's = [1, 2]*10000' '[x - y for x, y in zip(s[1:], s)]' 
100 loops, best of 3: 13.5 msec per loop 

$ python -mtimeit -s'import itertools as it; s = [1, 2]*10000' '[x - y for x, y in it.izip(s[1:], s)]' 
100 loops, best of 3: 8.4 msec per loop 

$ python -mtimeit -s'import itertools as it; import operator as op; s = [1, 2]*10000' 'list(it.starmap(op.sub, it.izip(s[1:], s)))' 
100 loops, best of 3: 6.38 msec per loop 
+8

sie tatsächlich für ein Trivial übermäßig kompliziert aussehen Aufgabe, insbesondere unter Berücksichtigung der vermuteten Erfahrung des OP. Wann wurden gewöhnliche For-Loops schlecht genutzt? –

+5

, wenn die doppelt so langsam und gruseliger zu lesen als ein Verständnis wurde. – aaronasterling

+0

Ok, ich profilierte und in diesem Fall sind sie nicht doppelt so langsam, aber sie sind immer noch die mit Abstand langsamste. 16,8 ms mit dem gleichen Eingang wie ich oben zeige. und mein Punkt darüber, dass sie noch unflexibler sind, um zu lesen, steht noch. – aaronasterling

42

Verwenden range ist völlig in Ordnung. Bei der Programmierung (wie in der Mathematik) geht es jedoch darum, Abstraktionen aufzubauen. Fortlaufende Paare [(x0, x1), (x1, x2), ..., (xn-2, xn-1)], werden paarweise Kombinationen genannt, siehe zum Beispiel eine recipe in the itertools docs. Sobald Sie diese Funktion in Ihrem Toolset haben, können Sie schreiben:

for x, y in pairwise(xs): 
    print(y - x) 

Oder als Generator Ausdruck:

consecutive_diffs = (y - x for (x, y) in pairwise(xs)) 
0

Hier ist das Beispiel aus der itertools reciepes ist:

from itertools import tee 

def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = tee(iterable) 
    next(b, None) 
    return zip(a, b) 

Was ist nicht sehr lesbar. Wenn Sie lieber etwas verständlicher und verstehen, wie Generatoren arbeiten, hier ein bisschen länger Beispiel mit dem gleichen Ergebnis:

def pairwise(it): 
    """ 
    Walk a list in overlapping pairs. 

    >>> list(pairwise([0, 1, 2, 3, 4, 5])) 
    [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)] 
    """ 
    it = iter(it) 
    start = None 
    while True: 
     if not start: 
      start = next(it) 
     end = next(it) 
     yield start, end 
     start = end 
0
def pairwise(iterable): 
    i = iter(iterable) 
    while True: 
     yield next(i), next(i, '') 
+0

Sie sollten einen Kommentar zum Code hinzufügen. – timiTao

+0

Während dieser Code die Frage beantworten kann, verbessert einen zusätzlichen Kontext, warum und/oder wie dieser Code die Frage beantwortet, seinen langfristigen Wert. –

Verwandte Themen