В python, как мне сделать что-то вроде:
for car in cars:
# Skip first and last, do work for rest
В python, как мне сделать что-то вроде:
for car in cars:
# Skip first and last, do work for rest
Другие ответы работают только для последовательности.
Для любой итерации пропустить первый элемент:
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
Вы можете использовать эту концепцию для любой последовательности.
Вот более общая функция генератора, которая пропускает любое количество элементов из начала и конца итерации:
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]
Лучший способ пропустить первый элемент (ы):
from itertools import islice
for car in islice(cars, 1, None):
# do something
islice в этом случае вызывается с начальной точкой 1 и конечной точкой None, означающей конец итератора.
Чтобы иметь возможность пропускать элементы с конца итерации, вам нужно знать его длину (всегда возможно для списка, но не обязательно для всего, что вы можете повторить). например, islice (автомобили, 1, len (cars) -1) пропустит первый и последний пункты в списке автомобилей.
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
На основе @SvenMarnach Answer, но бит проще и без использования 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
Ну, ваш синтаксис на самом деле не Python.
Итерации в Python превышают содержимое контейнеров (ну, технически это над итераторами), с синтаксисом for item in container
. В этом случае контейнер представляет собой список cars
, но вы хотите пропустить первый и последний элементы, так что это означает cars[1:-1]
(списки python основаны на нуле, отрицательные числа подсчитываются с конца, а :
- синтаксиса среза.
Итак, вы хотите
for c in cars[1:-1]:
do something with c
Альтернативный метод:
for idx, car in enumerate(cars):
# Skip first line.
if not idx:
continue
# Skip last line.
if idx + 1 == len(cars):
continue
# Real code here.
print car
Если cars
- это последовательность, которую вы можете просто сделать
for car in cars[1:-1]:
pass
Я делаю это так, хотя это выглядит как хак, который он работает каждый раз:
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
Проект 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
Здесь мой предпочтительный выбор. Это не требует добавления многого в цикл, и использует только встроенные инструменты.
Идти от:
for item in my_items:
do_something(item)
чтобы:
for i, item in enumerate(my_items):
if i == 0:
continue
do_something(item)