Ответы:
Другие ответы работают только для последовательности.
Для любой итерации, чтобы пропустить первый элемент:
itercars = iter(cars)
next(itercars)
for car in itercars:
# do work
Если вы хотите пропустить последний, вы можете сделать:
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'
Чтобы пропустить первый элемент в Python, вы можете просто написать
for car in cars[1:]:
# Do What Ever you want
или пропустить последний элемент
for car in cars[:-1]:
# Do What Ever you want
Вы можете использовать эту концепцию для любой последовательности.
Лучший способ пропустить первый пункт (ы):
from itertools import islice
for car in islice(cars, 1, None):
# do something
islice в этом случае вызывается с начальной точкой 1 и конечной точкой None, что означает конец итератора.
Чтобы иметь возможность пропустить элементы с конца итерируемого, вам нужно знать его длину (всегда возможно для списка, но не обязательно для всего, что вы можете повторять). например, islice (cars, 1, len (cars) -1) пропустит первый и последний элементы в списке автомобилей.
isliceдовольно хорошо, не зная длины или хранения в памяти больше элементов одновременно, чем это абсолютно необходимо.
isliceто, что передается deque, а не весь итератор, и это только длина количества элементов, которые нужно пропустить в конце. Он не хранит весь итератор в памяти.
Вот более общая функция генератора, которая пропускает любое количество элементов от начала и конца итерируемого:
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(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
at_end == 0.
skip(xrange(10000000), 1)будет использовать at_end=0, поэтому параметр to deque()будет islice(it, 0), который будет потреблять только ноль элементов it. Это не займет много памяти.
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
listв качестве имени переменной
listможет быть связано. Вот почему вы не должны , а не можете использовать его.
Пример:
mylist=['one'.'two','three'.'four'.'five']
for i in mylist[1:]:
print(i)
В индексе Python, начиная с 0, мы можем использовать оператор нарезки для выполнения манипуляций в итерации.
for i in range(1,-1):
Основано на Ответе @SvenMarnach, но немного проще и без использования 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]
Также обратите внимание, на основании моего timeitрезультата, это немного быстрее, чем решение 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(), вы все еще создаете весь список в памяти для генератора, верно? (твое it1)
Ну, ваш синтаксис не совсем Python для начала.
Итерации в Python заканчиваются содержимым контейнеров (ну, технически это итераторы), с синтаксисом for item in container. В этом случае контейнером является carsсписок, но вы хотите пропустить первый и последний элементы, что означает cars[1:-1](списки Python начинаются с нуля, отрицательные числа отсчитываются с конца, и: синтаксис разбивается на части).
Так ты хочешь
for c in cars[1:-1]:
do something with c
Вот мой предпочтительный выбор. Это не требует добавления многого в цикл, и использует только встроенные инструменты.
Идти от:
for item in my_items:
do_something(item)
чтобы:
for i, item in enumerate(my_items):
if i == 0:
continue
do_something(item)
Если carsэто последовательность, которую вы можете просто сделать
for car in cars[1:-1]:
pass
more_itertoolsПроект распространяется itertools.isliceобрабатывать отрицательные индексы.
пример
import more_itertools as mit
iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']
Таким образом, вы можете элегантно применить элементы среза между первым и последним элементами итерируемого элемента:
for car in mit.islice_extended(cars, 1, -1):
# do something
Я делаю это так, хотя это выглядит как хак, оно работает каждый раз:
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. логика в том , что она добавляет «счетчик» для каждого значения , которое вы можете целевую например , сif n == some_value. в этом примере он будет делать что-то для каждого экземпляра i, кроме первого.