Respostas:
As outras respostas funcionam apenas para uma sequência.
Para qualquer iterável, pule o primeiro item:
itercars = iter(cars)
next(itercars)
for car in itercars:
# do work
Se você quiser pular a última, você pode fazer:
itercars = iter(cars)
# add 'next(itercars)' here if you also want to skip the first
prev = next(itercars)
for car in itercars:
# do work on 'prev' not 'car'
# at end of loop:
prev = car
# now you can do whatever you want to do to the last one on 'prev'
Para pular o primeiro elemento do Python, você pode simplesmente escrever
for car in cars[1:]:
# Do What Ever you want
ou para pular o último elem
for car in cars[:-1]:
# Do What Ever you want
Você pode usar esse conceito para qualquer sequência.
A melhor maneira de pular os primeiros itens é:
from itertools import islice
for car in islice(cars, 1, None):
# do something
O islice nesse caso é chamado com um ponto inicial de 1 e um ponto final de Nenhum, significando o final do iterador.
Para poder pular itens do final de uma iterável, você precisa saber o seu comprimento (sempre possível para uma lista, mas não necessariamente para tudo em que você pode iterar). por exemplo, islice (carros, 1, len (carros) -1) pulará o primeiro e o último itens da lista de carros.
islice
muito bem, sem saber o tamanho ou armazenar mais itens na memória ao mesmo tempo do que o absolutamente necessário.
islice
é o que é passado para o deque
iterador, não para todo, e é apenas o tamanho do número de itens a serem ignorados no final. Não armazena o iterador inteiro na memória.
Aqui está uma função geradora mais geral que ignora qualquer número de itens do início e do final de um iterável:
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
for x in itertools.islice(it, at_start):
pass
queue = collections.deque(itertools.islice(it, at_end))
for x in it:
queue.append(x)
yield queue.popleft()
Exemplo de uso:
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
at_end == 0
.
skip(xrange(10000000), 1)
irá usar at_end=0
, então o parâmetro to deque()
será islice(it, 0)
, que consumirá apenas zero elementos de it
. Isso não vai ocupar muita memória.
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
list
como um nome de variável
list
pode ser ligado novamente. É por isso que você não deve usá-lo , e não pode .
Baseado na resposta de @SvenMarnach, mas um pouco mais simples e sem usar o deque
>>> def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
it = itertools.islice(it, at_start, None)
it, it1 = itertools.tee(it)
it1 = itertools.islice(it1, at_end, None)
return (next(it) for _ in it1)
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
>>> list(skip(range(10), at_start=2, at_end=5))
[2, 3, 4]
Observe também que, com base no meu timeit
resultado, isso é marginalmente mais rápido que a solução de deque
>>> iterable=xrange(1000)
>>> stmt1="""
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
it = itertools.islice(it, at_start, None)
it, it1 = itertools.tee(it)
it1 = itertools.islice(it1, at_end, None)
return (next(it) for _ in it1)
list(skip(iterable,2,2))
"""
>>> stmt2="""
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
for x in itertools.islice(it, at_start):
pass
queue = collections.deque(itertools.islice(it, at_end))
for x in it:
queue.append(x)
yield queue.popleft()
list(skip(iterable,2,2))
"""
>>> timeit.timeit(stmt = stmt1, setup='from __main__ import iterable, skip, itertools', number = 10000)
2.0313770640908047
>>> timeit.timeit(stmt = stmt2, setup='from __main__ import iterable, skip, itertools, collections', number = 10000)
2.9903135454296716
tee()
, você ainda está criando uma lista inteira na memória para o gerador, certo? (your it1
)
Exemplo:
mylist=['one'.'two','three'.'four'.'five']
for i in mylist[1:]:
print(i)
No índice python, inicie em 0, podemos usar o operador slicing para fazer manipulações na iteração.
for i in range(1,-1):
Bem, para começar, sua sintaxe não é realmente Python.
As iterações no Python estão sobre o conteúdo dos contêineres (bem, tecnicamente sobre os iteradores), com uma sintaxe for item in container
. Nesse caso, o contêiner é a cars
lista, mas você deseja pular o primeiro e o último elementos, o que significa cars[1:-1]
(as listas python são baseadas em zero, os números negativos são contados a partir do final e :
estão cortando a sintaxe.
Então você quer
for c in cars[1:-1]:
do something with c
Aqui está a minha escolha preferida. Não requer muito acréscimo ao loop e não usa nada além de ferramentas internas.
Vá de:
for item in my_items:
do_something(item)
para:
for i, item in enumerate(my_items):
if i == 0:
continue
do_something(item)
Se cars
é uma sequência, você pode simplesmente fazer
for car in cars[1:-1]:
pass
O more_itertools
projeto se estende itertools.islice
para lidar com índices negativos.
Exemplo
import more_itertools as mit
iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']
Portanto, você pode aplicá-lo de forma elegante a elementos de fatia entre o primeiro e o último itens de um iterável:
for car in mit.islice_extended(cars, 1, -1):
# do something
for n, i in enumerate(cars): if n!= 0: do something to i
. a lógica é que ele adiciona um 'contador' a cada valor que você pode segmentar, por exemploif n == some_value
. neste exemplo, faria algo para cada instância de i, exceto a primeira.