Como percorrer todos, exceto o último item de uma lista?


160

Gostaria de percorrer uma lista comparando cada item com o item a seguir.

Existe uma maneira de percorrer todos os itens, exceto o último, usando x em y? Eu preferiria fazê-lo sem usar índices, se puder.

Nota

O freespace respondeu à minha pergunta real, e é por isso que aceitei a resposta, mas o SilentGhost respondeu à pergunta que eu deveria ter feito.

Desculpas pela confusão.

Respostas:


316
for x in y[:-1]

Se yfor um gerador, o acima não funcionará.


Isso responde à minha pergunta, obrigado, mas esqueci de perguntar como obteria o item após x. Isso é possível?
David Sykes

3
- 1 Não acho que isso responda à pergunta. Não está comparando cada item com o próximo. - odwl 0 secs
odwl

4
Eu acho que sim. O autor disse que gostaria de fazer o X e perguntou como ele pode fazer o Y. Eu respondi como ele pode fazer o Y. Que ele aceitasse a minha resposta indicaria que eu respondi a pergunta que ele fez, se não a pergunta que ele realmente queria fazer. O Asker pode rebaixar esta resposta.
Freespace

7
Só porque o OP deveria ter feito outra pergunta no primeiro, não significa que sua pergunta e essa resposta não sejam muito úteis para os outros. +1
Prof. Falken,

1
Você mencionou que isso não funciona para geradores. Qual é a alternativa quando yé um gerador?
Joost

50

a maneira mais fácil de comparar o item de sequência com o seguinte:

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

15
Isso responde à pergunta que eu gostaria de ter feito. Obrigado
David Sykes

3
Na verdade, você pode omitir a primeira fatia, já que o zip trunca a lista mais longa para o comprimento da menor. Isso economizará uma criação de lista. (Apenas no caso de você está lidando com enormes listas Mas, nesse caso, você deve seguir a abordagem de Formigas Aasma, que não copia nada..)
Bayer

19

Se você deseja obter todos os elementos no par de seqüências, use esta abordagem (a função pairwise é dos exemplos no módulo 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

Se você precisar comparar o último valor com algum valor especial, encadeie esse valor até o final

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

Por favor, note que o uso do seguinte para sombras em nomes de variáveis embutidas
SilentGhost

1
Pessoalmente, não me importo de sombrear menos os componentes usados ​​quando o escopo da variável é pequeno e o nome é bom para facilitar a leitura. No entanto, editou os nomes das variáveis ​​para manter boas práticas de codificação.
Ants Aasma

5

se você quisesse comparar o enésimo item com o n + 1 o item da lista, também poderia fazer com

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

note que não há código rígido acontecendo lá. Isso deve ser bom, a menos que você sinta o contrário.


3
Você pode substituir len (lista [: - 1]) por len (lista) - 1 para evitar uma cópia da lista. E evitar o uso de uma variável chamada lista ...
Remy em branco

2

Para comparar cada item com o próximo em um iterador sem instanciar uma lista:

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

2
isso é exatamente o que foi sugerido por Ants Aasma stackoverflow.com/questions/914715/…
SilentGhost

1

Isso responde ao que o OP deveria ter solicitado , ou seja, percorre uma lista comparando elementos consecutivos (excelente resposta do SilentGhost ), mas generalizada para qualquer grupo ( n-grama ): 2, 3, ... n:

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

Exemplos:

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

Explicações:

  • l[start:] gera uma lista / gerador a partir do índice start
  • *listou *generator: passa todos os elementos para a função delimitadora zipcomo se estivesse gravadazip(elem1, elem2, ...)

Nota:

AFAIK, esse código é o mais preguiçoso possível. Não testado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.