Antworten:
Die anderen Antworten funktionieren nur für eine Sequenz.
Um das erste Element zu überspringen:
itercars = iter(cars)
next(itercars)
for car in itercars:
# do work
Wenn Sie den letzten überspringen möchten, können Sie Folgendes tun:
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'
Um das erste Element in Python zu überspringen, können Sie einfach schreiben
for car in cars[1:]:
# Do What Ever you want
oder um das letzte Element zu überspringen
for car in cars[:-1]:
# Do What Ever you want
Sie können dieses Konzept für jede Sequenz verwenden.
Der beste Weg, um die ersten Elemente zu überspringen, ist:
from itertools import islice
for car in islice(cars, 1, None):
# do something
islice wird in diesem Fall mit einem Startpunkt von 1 und einem Endpunkt von None aufgerufen, was das Ende des Iterators bedeutet.
Um Elemente vom Ende einer Iterable überspringen zu können, müssen Sie deren Länge kennen (immer möglich für eine Liste, aber nicht unbedingt für alles, was Sie iterieren können). Zum Beispiel überspringt islice (Autos, 1, len (Autos) -1) die ersten und letzten Elemente in der Autoliste.
islice
, ohne die Länge zu kennen oder mehr Elemente gleichzeitig im Speicher zu speichern, als unbedingt erforderlich.
islice
ist das, was an deque
den gesamten Iterator übergeben wird, und es ist nur die Länge der Anzahl der Elemente, die am Ende übersprungen werden sollen. Es wird nicht der gesamte Iterator gespeichert.
Hier ist eine allgemeinere Generatorfunktion, die eine beliebige Anzahl von Elementen vom Anfang und Ende einer Iterable überspringt:
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()
Anwendungsbeispiel:
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
at_end == 0
.
skip(xrange(10000000), 1)
wird verwendet at_end=0
, also wird der Parameter deque()
sein islice(it, 0)
, der nur null Elemente von verbraucht it
. Dies nimmt nicht viel Speicherplatz in Anspruch.
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
list
als Variablenname verwenden
list
kann neu gebunden werden. Deshalb sollten Sie es nicht verwenden , sondern können es nicht verwenden.
Basierend auf der Antwort von @SvenMarnach, aber etwas einfacher und ohne Verwendung von 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]
Beachten Sie auch, dass dies aufgrund meines timeit
Ergebnisses geringfügig schneller ist als die Deque-Lösung
>>> 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()
Sie immer noch eine ganze Liste im Speicher für den Generator, oder? (Ihr it1
)
Beispiel:
mylist=['one'.'two','three'.'four'.'five']
for i in mylist[1:]:
print(i)
Im Python-Index ab 0 können wir den Slicing-Operator verwenden, um Manipulationen in der Iteration vorzunehmen.
for i in range(1,-1):
Nun, Ihre Syntax ist zunächst nicht wirklich Python.
Iterationen in Python sind über den Inhalt von Containern (technisch gesehen über Iteratoren) mit einer Syntax for item in container
. In diesem Fall ist der Container die cars
Liste, aber Sie möchten das erste und das letzte Element überspringen. Das bedeutet, dass cars[1:-1]
Python-Listen auf Null basieren, negative Zahlen vom Ende an zählen und die :
Syntax aufteilen.
Also du möchtest
for c in cars[1:-1]:
do something with c
Hier ist meine bevorzugte Wahl. Es erfordert nicht viel Hinzufügen zur Schleife und verwendet nur eingebaute Werkzeuge.
Gehe von:
for item in my_items:
do_something(item)
zu:
for i, item in enumerate(my_items):
if i == 0:
continue
do_something(item)
Wenn cars
es sich um eine Sequenz handelt, können Sie dies einfach tun
for car in cars[1:-1]:
pass
Das more_itertools
Projekt erstreckt sich itertools.islice
auf negative Indizes.
Beispiel
import more_itertools as mit
iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']
Daher können Sie es elegant auf Slice-Elemente zwischen dem ersten und dem letzten Element einer Iterable anwenden:
for car in mit.islice_extended(cars, 1, -1):
# do something
Ich mache es so, obwohl es wie ein Hack aussieht, funktioniert es jedes Mal:
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
. Die Logik ist, dass es jedem Wert einen 'Zähler' hinzufügt, auf den Sie dann zB zielen könnenif n == some_value
. In diesem Beispiel würde es mit jeder Instanz von i etwas tun, mit Ausnahme der ersten.