在python for循环中跳过第一个条目?

在python中,我如何做这样的事情:

for car in cars:
# Skip first and last, do work for rest
313239 次浏览

这段代码跳过列表的第一个和最后一个元素:

for item in list_name[1:-1]:
#...do whatever

要跳过Python中的第一个元素,您可以简单地编写

for car in cars[1:]:
# Do What Ever you want

或者跳过最后一个elem

for car in cars[:-1]:
# Do What Ever you want

你可以将此概念用于任何sequence(但不能用于任何iterable)。

其他答案只适用于一个序列。

对于任何可迭代对象,跳过第一项:

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。

Python中的迭代是在容器的内容之上(好吧,技术上是在迭代器之上),语法为for item in container。在这种情况下,容器是cars列表,但你想跳过第一个和最后一个元素,所以这意味着cars[1:-1] (python列表是从零开始的,负数从末尾开始计数,:是切片语法。

所以你想

for c in cars[1:-1]:
do something with c

下面是一个更通用的生成器函数,它从可迭代对象的开头和结尾跳过任意数量的项:

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):
pass
# do something

在这种情况下,islice被调用,起始点为1,结束点为None,表示iterable的结束。

为了能够从iterable的末尾跳过项,你需要知道它的长度(对于列表总是可能的,但不一定对于你可以迭代的所有东西)。例如,islice(cars, 1, len(cars)-1)将跳过cars中的第一项和最后一项。

基于@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

另一种方法:

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

我是这样做的,尽管它看起来像一个黑客,但它每次都有效:

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']

因此,你可以优雅地将it切片元素应用于iterable的第一个和最后一个元素之间:

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)

例子:

mylist=['one','two','three','four','five']
for i in mylist[1:]:
print(i)

在python中,索引从0开始,我们可以使用切片操作符进行迭代操作。

for i in range(1,-1):

支持itertools.chain的良好解决方案是使用itertools.islice来获取可迭代对象的切片:

your_input_list = ['list', 'of', 'things']
for i, variant in list(itertools.islice(enumerate(some_function_that_will_output_itertools_chain(your_input_list)), 1, None)):
"""
# No need for unnecessary conditions like this:
if i == 0:
continue
"""
variant = list(variant) # (optional) converting back to list
print(variant)