Risposte:
Le altre risposte funzionano solo per una sequenza.
Per ogni iterabile, per saltare il primo elemento:
itercars = iter(cars)
next(itercars)
for car in itercars:
# do work
Se vuoi saltare l'ultimo, puoi fare:
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'
Per saltare il primo elemento in Python puoi semplicemente scrivere
for car in cars[1:]:
# Do What Ever you want
o per saltare l'ultimo elem
for car in cars[:-1]:
# Do What Ever you want
Puoi usare questo concetto per qualsiasi sequenza.
Il modo migliore per saltare i primi elementi è:
from itertools import islice
for car in islice(cars, 1, None):
# do something
islice in questo caso viene invocato con un punto iniziale di 1 e un punto finale di Nessuno, che indica la fine dell'iteratore.
Per saltare gli elementi dalla fine di un iterabile, devi conoscerne la lunghezza (sempre possibile per un elenco, ma non necessariamente per tutto ciò su cui puoi iterare). ad esempio, islice (auto, 1, len (auto) -1) salterà il primo e l'ultimo elemento nell'elenco auto.
isliceabbastanza bene, senza conoscere la lunghezza o memorizzare più elementi contemporaneamente in memoria di quanto assolutamente necessario.
isliceè ciò che viene passato a deque, non l'intero iteratore, ed è solo la lunghezza del numero di elementi da saltare alla fine. Non memorizza l'intero iteratore in memoria.
Ecco una funzione del generatore più generale che salta un numero qualsiasi di elementi dall'inizio e dalla fine di un iterabile:
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()
Esempio di utilizzo:
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
at_end == 0.
skip(xrange(10000000), 1)userà at_end=0, quindi il parametro deque()sarà islice(it, 0), che consumano solo zero elementi di it. Questo non richiederà molta memoria.
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
listcome nome variabile
listpuò essere rilegato. Ecco perché non dovresti , piuttosto che non puoi , usarlo.
Basato sulla risposta di @SvenMarnach, ma un po 'più semplice e senza usare 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]
Inoltre, in base al mio timeitrisultato, questo è leggermente più veloce della soluzione di 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(), stai ancora creando un intero elenco in memoria per il generatore, giusto? (tuo it1)
Esempio:
mylist=['one'.'two','three'.'four'.'five']
for i in mylist[1:]:
print(i)
Nell'indice python a partire da 0, possiamo usare l'operatore slicing per effettuare manipolazioni nell'iterazione.
for i in range(1,-1):
Bene, la tua sintassi non è proprio Python per cominciare.
Le iterazioni in Python sono sul contenuto dei container (beh, tecnicamente è su iteratori), con una sintassi for item in container. In questo caso, il contenitore è l' carselenco, ma si desidera saltare il primo e l'ultimo elemento, quindi ciò significa cars[1:-1](gli elenchi di Python sono basati su zero, i numeri negativi contano dalla fine e: sta tagliando la sintassi.
Quindi tu vuoi
for c in cars[1:-1]:
do something with c
Ecco la mia scelta preferita. Non richiede di aggiungere molto al loop e non usa altro che strumenti integrati.
Andare da:
for item in my_items:
do_something(item)
per:
for i, item in enumerate(my_items):
if i == 0:
continue
do_something(item)
Se carsè una sequenza che puoi semplicemente fare
for car in cars[1:-1]:
pass
Il more_itertoolsprogetto si estendeitertools.islice per gestire indici negativi.
Esempio
import more_itertools as mit
iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']
Pertanto, è possibile applicare elegantemente gli elementi di divisione tra il primo e l'ultimo elemento di un iterabile:
for car in mit.islice_extended(cars, 1, -1):
# do something
Lo faccio in questo modo, anche se sembra un hack funziona sempre:
ls_of_things = ['apple', 'car', 'truck', 'bike', 'banana']
first = 0
last = len(ls_of_things)
for items in ls_of_things:
if first == 0
first = first + 1
pass
elif first == last - 1:
break
else:
do_stuff
first = first + 1
pass
for n, i in enumerate(cars): if n!= 0: do something to i. la logica è che aggiunge un "contatore" a ciascun valore che può essere scelto come target, ad esif n == some_value. in questo esempio farebbe qualcosa per ogni istanza di i, tranne per il primo.