2008-11-27 7 views

Antwort

0

Iteratoren haben nur die next() Methode, so dass Sie nicht vorwärts oder rückwärts schauen können, Sie können nur das nächste Element bekommen.

enumerate (iterierbar) kann nützlich sein, wenn Sie eine Liste oder ein Tupel iterieren.

-7

Der einfachste Weg ist es, die Liste für das Element suchen:

def get_previous(l, item): 
    idx = l.find(item) 
    return None if idx == 0 else l[idx-1] 

Natürlich funktioniert dies nur, wenn die Liste nur eindeutige Elemente enthält. Die andere Lösung ist:

for idx in range(len(l)): 
    item = l[idx] 
    if item == 2: 
     l[idx-1] 
1

Ich glaube nicht, dass es eine einfache Art und Weise ist, vor allem, dass ein iterable ein Generator sein kann (keine zurück). Es gibt eine anständige Abhilfe, die sich auf ausdrücklich den Index in der Schleife vorbei:

for itemIndex, item in enumerate(l): 
    if itemIndex>0: 
     previousItem = l[itemIndex-1] 
    else: 
     previousItem = None 

Die enumerate() Funktion ein builtin ist.

61

als Generator Funktion ausgedrückt:

def neighborhood(iterable): 
    iterator = iter(iterable) 
    prev_item = None 
    current_item = next(iterator) # throws StopIteration if empty. 
    for next_item in iterator: 
     yield (prev_item, current_item, next_item) 
     prev_item = current_item 
     current_item = next_item 
    yield (prev_item, current_item, None) 

Verbrauch:

for prev,item,next in neighborhood(l): 
    print prev, item, next 
+1

Ich könnte "prev, item = item, next" in diesem Fall tun. –

+1

Um diesen Zyklus unendlich (ohne StopIteration) zu machen, muss man 'von itertools import cycle' und die zweite Zeile ändern in:' iterator = cycle (iterable) ' –

+0

Ist es weniger Pythonic, in diesem Kontext Enumerate zu verwenden? – batbrat

6

Wenn mit Generatoren zu tun, wo man einige Kontext benötigen, verwende ich oft die unter Nutzenfunktion eine Schiebefenster-Ansicht geben auf ein Iterator:

import collections, itertools 

def window(it, winsize, step=1): 
    """Sliding window iterator.""" 
    it=iter(it) # Ensure we have an iterator 
    l=collections.deque(itertools.islice(it, winsize)) 
    while 1: # Continue till StopIteration gets raised. 
     yield tuple(l) 
     for i in range(step): 
      l.append(it.next()) 
      l.popleft() 

Es wird eine Ansicht der Sequenz N Elemente um um generieren Ime, verschiebende Schrittplätze rüber. z.B.

>>> list(window([1,2,3,4,5],3)) 
[(1, 2, 3), (2, 3, 4), (3, 4, 5)] 

Wenn in Look-Ahead mit/hinter Situationen, in denen Sie müssen auch mit Zahlen umgehen können, ohne einen nächsten oder vorherigen Wert zu haben, können Sie Pad, um die Sequenz mit einem entsprechenden Wert wie Keine möchten.

l= range(10) 
# Print adjacent numbers 
for cur, next in window(l + [None] ,2): 
    if next is None: print "%d is the last number." % cur 
    else: print "%d is followed by %d" % (cur,next) 
0

Sofort zurück?

Sie meinen das folgende, oder?

previous = None 
for item in someList: 
    if item == target: break 
    previous = item 
# previous is the item before the target 

Wenn Sie n vorherigen Artikel möchten, können Sie dies tun mit einer Art Kreis Schlange von Größe n.

queue = [] 
for item in someList: 
    if item == target: break 
    queue .append(item) 
    if len(queue) > n: queue .pop(0) 
if len(queue) < n: previous = None 
previous = previous[0] 
# previous is *n* before the target 
9
l=[1,2,3] 
for i,item in enumerate(l): 
    if item==2: 
     get_previous=l[i-1] 
     print get_previous 

>>>1 
5

Überprüfen Sie die Looper-Dienstprogramm aus dem Tempita project aus. Es gibt Ihnen ein Wrapper-Objekt um den Loop-Artikel, der Eigenschaften wie vorherige, nächste, erste, letzte usw. bietet.

Werfen Sie einen Blick auf die source code für die Looper-Klasse, es ist ziemlich einfach. Es gibt noch andere solche Loop-Helfer, aber ich kann mich im Moment nicht an andere erinnern.

Beispiel:

> easy_install Tempita 
> python 
>>> from tempita import looper 
>>> for loop, i in looper([1, 2, 3]): 
...  print loop.previous, loop.item, loop.index, loop.next, loop.first, loop.last, loop.length, loop.odd, loop.even 
... 
None 1 0 2 True False 3 True 0 
1 2 1 3 False False 3 False 1 
2 3 2 None False True 3 True 0 
-2

Nicht sehr pythonic, aber wird es getan und ist einfach:

l=[1,2,3] 
for index in range(len(l)): 
    if l[index]==2: 
     l[index-1] 

TO DO: schützt die Kanten

5

Ich weiß, das alt ist, aber warum nicht nur enumerate verwenden?

l = ['adam', 'rick', 'morty', 'adam', 'billy', 'bob', 'wally', 'bob', 'jerry'] 

for i, item in enumerate(l): 
    if i == 0: 
     previous_item = None 
    else: 
     previous_item = l[i - 1] 

    if i == len(l) - 1: 
     next_item = None 
    else: 
     next_item = l[i + 1] 

    print('Previous Item:', previous_item) 
    print('Item:', item) 
    print('Next Item:', next_item) 
    print('') 

    pass 

Wenn Sie dies ausführen, werden Sie sehen, dass es vorherige und nächste Elemente erfasst und sich nicht um das Wiederholen von Elementen in der Liste kümmert.

+1

Warum die Downvotes? Dies ist in Ordnung und beinhaltet keine externen Bibliotheken oder spezielle Funktionen. –

+0

Die Frage hat auch nach dem vorherigen Artikel gefragt. Und funktioniert das nicht falsch, wenn sich ein Gegenstand wiederholt? "[1,2,1,3]"? – Teepeemm

+0

@Teepeemm, yeah, ich werde es mit einer Version aktualisieren, die die Anforderungen erfüllt. – DuckPuncher

21

Ein einfacher Weg.

l=[1,2,3] 
for i,j in zip(l, l[1:]): 
    print i, j 
+8

Ich habe das verwendet, aber erweitert, um zu vermeiden, dass die Start-/End-Elemente fallen gelassen wurden: 'für prev, cur, next in zip ([Keine] + l [: - 1], l, l [1:] + [Keine]) : ' – Maximus

+0

@Maximus: Dieser Kommentar sollte eine Antwort sein. Wirklich Genie! – Helio

0

Wenn Sie die Lösung wollen auf Iterables arbeiten, hat das itertools' docs ein Rezept, das genau das tut, was Sie wollen:

import itertools 

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

Wenn Sie Python 2.x verwenden, verwenden itertools.izip statt zip

Verwandte Themen