在python中跳过for循环中的第一个条目?
在python中,如何执行以下操作:在python中跳过for循环中的第一个条目?,python,Python,在python中,如何执行以下操作: for car in cars: # Skip first and last, do work for rest 要跳过Python中的第一个元素,只需编写 for car in cars[1:]: # Do What Ever you want 或者跳过最后一个元素 for car in cars[:-1]: # Do What Ever you want 您可以将此概念用于任何序列。如果cars是一个序列,您只需执行即可 fo
for car in cars:
# Skip first and last, do work for rest
要跳过Python中的第一个元素,只需编写
for car in cars[1:]:
# Do What Ever you want
或者跳过最后一个元素
for car in cars[:-1]:
# Do What Ever you want
您可以将此概念用于任何序列。如果
cars
是一个序列,您只需执行即可
for car in cars[1:-1]:
pass
其他答案只适用于一个序列 对于任何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中的迭代覆盖容器的内容(从技术上讲是覆盖迭代器),容器中的项使用语法
。在本例中,容器是cars
列表,但您希望跳过第一个和最后一个元素,因此这意味着cars[1:-1]
(python列表以零为基础,负数从末尾开始计数,:
是切片语法
所以你想要
for c in cars[1:-1]:
do something with c
下面是一个更通用的生成器函数,它从iterable的开头和结尾跳过任意数量的项:
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()
for car in mit.islice_extended(cars, 1, -1):
# do something
用法示例:
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
跳过第一项的最佳方法是:
在本例中,调用islice的起点为1,终点为None,表示迭代器结束
为了能够从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
该项目扩展了itertools.islice
以处理负指数
范例
import more_itertools as mit
iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']
因此,您可以在iterable的第一项和最后一项之间优雅地应用it切片元素:
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()
for car in mit.islice_extended(cars, 1, -1):
# do something
这是我的首选。它不需要在循环中添加太多内容,只使用内置工具
从:
对于my_项目中的项目:
做某事(项目)
致:
对于i,枚举中的项(我的项):
如果i==0:
持续
做某事(项目)
示例:
mylist=['one','two','three','four','five']
for i in mylist[1:]:
print(i)
在python索引从0开始的过程中,我们可以使用切片操作符在迭代中进行操作
for i in range(1,-1):
不要使用list
作为变量名OP只想跳过第一个元素。为什么:-1?它实际上不是保留的;名称list
可以重新绑定。这就是为什么你不应该而不是不能使用它。@luke14free,问题是跳过第一个元素,但他的代码注释暗示他确实想跳过第一个和最后一个元素@luke14free这是标题所说的,不是他在代码中键入的:“如果是第一个或最后一个,则跳过”不是针对所有人,而是针对所有人。内存使用情况如何?slice是否会生成子序列的新副本?@Voyager是的,它会生成新副本。可能需要为在=0
处添加快速路径。collections.deque(…)将立即通过迭代器。这意味着skip(xrange(10000000),1)将占用大量内存,即使它确实不应该占用内存。@RoeeShenberg:skip(xrange(10000000),1)
将在0处使用,因此deque()
的参数将是islice(it,0)
,它只会消耗中的零元素。这不会占用大量内存。请看Sven的(未充分理解)答案。他很好地使用islice
跳过了任何iterable开头和/或结尾的任意数量的项,而不知道长度或一次在内存中存储超过绝对必要的项。斯文的答案实际上是将整个迭代器存储在内存-集合中。deque将在迭代器中运行。尝试像collections.deque(xrange(10000000))这样的操作。如果要跳过第一项,则无需在内存中存储所有整数。islice
是传递给deque
的内容,而不是整个迭代器,它只是要在末尾跳过的项数的长度。它不会在内存中存储整个迭代器。这对iterable(例如生成器)不起作用,只有一个序列。我是新手,但我在enumerate(cars)中使用了n,i的:if n!=0:do something to i
。逻辑是,如果n==some_value
,它会为每个值添加一个“计数器”,然后您可以使用将其作为目标,例如。在本例中,它会对i的每个实例执行操作,但第一个除外。另请参见“s i find to do cars.pop(0)和cars.pop()效果很好。@dreamwork801我的答案和Sven的答案(我在第一条注释中链接了它们)适用于任何iterable,甚至是无限的,因为它们在迭代开始之前不需要对数据进行O(n)运算。你的建议和Abhjit的建议都只适用于序列,而不适用于任何iterable。使用tee()
,您仍然在内存中为生成器创建一个完整的列表,对吗?(您的it1
)