2009-05-27 16 views
98

Chciałbym przejrzeć listę sprawdzającą każdy z elementów podążający za nią.Jak przejść przez wszystkie, oprócz ostatniego elementu listy?

Czy istnieje sposób, w jaki mogę przechodzić przez wszystkie, oprócz ostatniego elementu, używając x dla y? Wolałbym to zrobić bez używania indeksów, jeśli mogę.

Uwaga

freespace odpowiedział na moje pytanie rzeczywistego, dlatego przyjąłem odpowiedź, ale SilentGhost odpowiedział na pytanie powinien poprosiłem.

Przeprosiny za zamieszanie.

Odpowiedz

196
for x in y[:-1] 

Jeśli y jest generatorem, powyższe nie będzie działać.

+0

To odpowiada na moje pytanie, dzięki, ale zapomniałem zapytać, w jaki sposób otrzymam przedmiot po x. czy to możliwe? –

+0

Wierzę, że instrukcja "else" pozwoli ci poradzić sobie z tym, co dzieje się po pętli, nie zapomnij ustawić x na ostatni element. – nevets1219

+2

- 1 Nie sądzę, że odpowiedź na pytanie. Nie porównuje on każdej pozycji z kolejną. - odwl 0 secs ago – odwl

18

Jeśli chcesz uzyskać wszystkie elementy w parze sekwencji, użyj tego podejścia (funkcja parowania pochodzi z przykładów w module 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 

Jeśli trzeba porównać ostatnią wartość w pewnej szczególnej wartości, łańcuch ten wynik do końca

for current, next_item in pairwise(chain(y, [None])): 
+0

proszę zauważyć, że użycie następnej dla zmiennej nazwy cieni wbudowanej – SilentGhost

+0

Ja osobiście nie mam nic przeciwko shadowingowi mniej używanych wbudowanych, gdy zakres zmiennej jest mały i nazwa jest dobra dla czytelności. Mimo to edytowano nazwy zmiennych, aby zachować dobre praktyki kodowania. –

4

jeśli chodziło o porównanie n-ty element z pozycji n + 1-go na liście można było rób tak samo jak z

nie ma tam twardego kodowania. To powinno być ok, chyba że czujesz się inaczej.

+2

Możesz zamienić len (list [: - 1]) na len (list) - 1, aby uniknąć kopiowania listy. I unikaj używania zmiennej o nazwie lista ... –

37

najprostszym sposobem, aby porównać element sekwencji z następujących czynności:

for i, j in zip(a, a[1:]): 
    # compare i (the current) to j (the following) 
+9

To odpowiada na pytanie, które chciałbym zadać. Dzięki –

+2

Właściwie możesz pominąć pierwszy kawałek, ponieważ zip obcina dłuższą listę do długości krótszego. Pozwoli to zaoszczędzić Ci jedno utworzenie listy. (Na wypadek, gdybyś miał do czynienia z ogromnymi listami, ale w takim wypadku powinieneś postępować zgodnie z podejściem AntsAasma, które niczego nie kopiuje.) – bayer

+0

dzięki, zwykle bezużyteczne, rzeczywiście wygląda czystsze. – SilentGhost

0

Aby porównać każdy element z następnego w iteracyjnej bez instancji listę:

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 
+1

to jest dokładnie to, co zasugerował Ants Aasma http://stackoverflow.com/questions/914715/python-looping-through-all- but-t-last-it-of-a-list/914786#914786 – SilentGhost

0

ta odpowiada co do OP powinien był zadać, tj. Przejść przez listę porównującą kolejne elementy (znakomita odpowiedź SilentGhost), ale uogólniony dla dowolnej grupy (n-gram): 2, 3, ... n:

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

Przykłady:

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)))) # == [] 

Objaśnienia:

  • l[start:] generuje listę AA/generator rozpoczynając od indeksu start
  • *list lub *generator: przechodzi cały elem enty do funkcji otaczającej zip jakby było napisane zip(elem1, elem2, ...)

Uwaga:

AFAIK ten kod jest tak leniwy, jak to tylko możliwe. Nie testowany.

Powiązane problemy