在python跳过for循环的第一个条目?
在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(汽车)-1)将跳过汽车列表中的第一个和最后一个项目。
for item in do_not_use_list_as_a_name[1:-1]: #...do whatever
那么,你的语法不是真正的Python开始。
Python中的迭代遍及容器的内容(呃,技术上它是迭代器的), for item in container
有一个语句。 在这种情况下,容器是cars
列表,但是你想跳过第一个和最后一个元素,所以这意味着cars[1:-1]
(python列表是从零开始的,负数从结尾计数,并且:
是切片语法。
所以你要
for c in cars[1:-1]: do something with c
基于@SvenMarnach的答案,但更简单一点,没有使用双端队列
>>> 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解决schemetimeit
快
>>> 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
如果cars
是一个序列,你可以做
for car in cars[1:-1]: pass
另一种方法:
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
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