在Python中,我该如何实现以下操作:
for car in cars:
# Skip first and last, do work for rest
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'
islice
跳过任意数量的可迭代对象开头和/或结尾的项,而不知道长度或一次在内存中存储更多的项比绝对必要的少。 - agfislice
是传递给 deque
的内容,而不是整个迭代器,并且它仅表示要跳过的项目数量的长度。它不会将整个迭代器存储在内存中。 - agf这里有一个更通用的生成器函数,它可以跳过可迭代对象开头和结尾的任意数量的项目:
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
添加快速路径。 - agf@RoeeShenberg: skip(xrange(10000000), 1)
会使用at_end=0
,因此deque()
的参数将是islice(it, 0)
,它只会消耗it
的零个元素。这不会占用太多内存。 - Sven Marnach这段代码跳过了列表的第一个和最后一个元素:
for item in list_name[1:-1]:
#...do whatever
list
并没有被保留;这个名称可以被重新绑定。所以你 不应该 而不是 不能 使用它。 - jscs例子:
mylist=['one','two','three','four','five']
for i in mylist[1:]:
print(i)
在Python中,索引从0开始,我们可以使用切片操作来进行迭代中的操作。
for i in range(1,-1):
这是我的首选方案。它不需要在循环中添加太多内容,只使用内置工具。
从以下状态开始:
for item in my_items:
do_something(item)
to:
for i, item in enumerate(my_items):
if i == 0:
continue
do_something(item)
嗯,您的语法实际上不是Python。
在Python中,迭代是针对容器的内容进行的(技术上是针对迭代器的),语法为 for item in container
。在这种情况下,容器是 cars
列表,但您想跳过第一个和最后一个元素,所以这意味着使用 cars [1:-1]
(Python列表从0开始计数,负数表示从末尾开始计数,:
是切片语法)。
所以您需要
for c in cars[1:-1]:
do something with c
基于 @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
)在内存中创建一个完整的列表,对吗? - Jabberwockey另一种方法:
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
for n, i in enumerate(cars): if n!= 0: do something to i
。这个逻辑是为每个值添加一个“计数器”,然后可以通过if n == some_value
来定位它。在这个例子中,它将对除第一个实例之外的每个 i 进行某些操作。 - user1063287