Odpowiedzi:
Pozostałe odpowiedzi działają tylko dla sekwencji.
W przypadku dowolnej iteracji pomiń pierwszy element:
itercars = iter(cars)
next(itercars)
for car in itercars:
# do work
Jeśli chcesz pominąć ostatni, możesz:
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'
Aby pominąć pierwszy element w Pythonie, możesz po prostu napisać
for car in cars[1:]:
# Do What Ever you want
lub pominąć ostatni elem
for car in cars[:-1]:
# Do What Ever you want
Możesz użyć tej koncepcji do dowolnej sekwencji.
Najlepszym sposobem na pominięcie pierwszych elementów jest:
from itertools import islice
for car in islice(cars, 1, None):
# do something
islice w tym przypadku jest wywoływane z punktem początkowym 1 i punktem końcowym Brak, co oznacza koniec iteratora.
Aby móc pominąć elementy z końca iteracji, musisz znać jego długość (zawsze jest to możliwe dla listy, ale niekoniecznie dla wszystkiego, co możesz iterować). na przykład islice (samochody, 1, len (samochody) -1) pomija pierwszy i ostatni element na liście samochodów.
islicecałkiem dobrze, bez znajomości długości lub przechowywania większej liczby przedmiotów na raz, niż jest to absolutnie konieczne.
isliceJest to, co jest przekazywane do deque, a nie całego iterator, i to tylko długość liczby elementów, aby przejść na koniec. Nie przechowuje całego iteratora w pamięci.
Oto bardziej ogólna funkcja generatora, która pomija dowolną liczbę elementów od początku i końca iteracji:
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()
Przykładowe użycie:
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
at_end == 0.
skip(xrange(10000000), 1)użyje at_end=0, więc parametrem deque()będzie islice(it, 0), który będzie zużywał tylko zero elementów it. To nie zajmie dużo pamięci.
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
listjako nazwy zmiennej
listmoże zostać ponownie powiązana. Dlatego nie powinien , raczej niż nie , użyj go.
Na podstawie odpowiedzi @ SvenaMarnacha, ale nieco prostsze i bez użycia 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]
Również uwaga, w oparciu o mój timeitwynik, jest to nieznacznie szybsze niż rozwiązanie 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(), nadal tworzysz całą listę pamięci generatora, prawda? (twój it1)
Przykład:
mylist=['one'.'two','three'.'four'.'five']
for i in mylist[1:]:
print(i)
W indeksie pythonowym zaczynającym się od 0, możemy używać operatora krojenia, aby manipulować iteracją.
for i in range(1,-1):
Cóż, twoja składnia nie jest tak naprawdę Pythonem.
Iteracje w Pythonie są ponad zawartością kontenerów (cóż, technicznie jest to ponad iteratorami), ze składnią for item in container. W tym przypadku kontener jest carslistą, ale chcesz pominąć pierwszy i ostatni element, co oznacza cars[1:-1](listy python są liczone od zera, liczby ujemne liczą się od końca i :kroi składnię.
Więc chcesz
for c in cars[1:-1]:
do something with c
Oto mój preferowany wybór. Nie wymaga dodawania wiele do pętli i używa tylko wbudowanych narzędzi.
Przejdź od:
for item in my_items:
do_something(item)
do:
for i, item in enumerate(my_items):
if i == 0:
continue
do_something(item)
Jeśli carsjest to sekwencja, którą możesz po prostu zrobić
for car in cars[1:-1]:
pass
The more_itertoolsProjekt rozszerzaitertools.islice obsłużyć ujemnych indeksów.
Przykład
import more_itertools as mit
iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']
Dlatego możesz elegancko zastosować elementy do wycinania między pierwszym a ostatnim elementem iteracji:
for car in mit.islice_extended(cars, 1, -1):
# do something
Robię to w ten sposób, mimo że wygląda to na hack, działa za każdym razem:
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. logika polega na tym, że dodaje „licznik” do każdej wartości, którą można następnie celować npif n == some_value. za pomocą . w tym przykładzie zrobiłby coś dla każdego wystąpienia i, z wyjątkiem pierwszego.