Відповіді:
Інші відповіді працюють лише для послідовності.
Щоб пропустити перший пункт:
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 (автомобілі, 1, len (машини) -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, тому параметр deque()буде islice(it, 0), який буде споживати лише нульові елементи it. Це не займе багато пам’яті.
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
listяк ім'я змінної
listможна повторно зв'язати. Ось чому ви не повинні , а не можуть , використовувати його.
На основі відповіді @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)
Приклад:
mylist=['one'.'two','three'.'four'.'five']
for i in mylist[1:]:
print(i)
В індексі python починаючи з 0, ми можемо використовувати оператор нарізки для здійснення маніпуляцій в ітерації.
for i in range(1,-1):
Ну, ваш синтаксис насправді не 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, за винятком першого.