Python 如何访问for循环中的上一个/下一个元素?
在使用Python 如何访问for循环中的上一个/下一个元素?,python,for-loop,Python,For Loop,在使用for循环时,是否有方法访问列表的下一个或上一个元素(或元组或其他iterable) l = [1, 2, 3] for item in l: if item == 2: get_previous(l, item) 迭代器只有next()方法,因此不能向前或向后看,只能获取下一项 如果要迭代列表或元组,enumerate(iterable)可能很有用。最简单的方法是在列表中搜索项: def get_previous(l, item): idx = l.fi
for
循环时,是否有方法访问列表的下一个或上一个元素(或元组或其他iterable)
l = [1, 2, 3]
for item in l:
if item == 2:
get_previous(l, item)
迭代器只有next()方法,因此不能向前或向后看,只能获取下一项
如果要迭代列表或元组,enumerate(iterable)可能很有用。最简单的方法是在列表中搜索项:
def get_previous(l, item):
idx = l.find(item)
return None if idx == 0 else l[idx-1]
当然,这仅在列表仅包含唯一项时有效。另一种解决办法是:
for idx in range(len(l)):
item = l[idx]
if item == 2:
l[idx-1]
我不认为有一个简单的方法,特别是因为一个iterable可以是一个(禁止返回)。您可以通过将元素的索引传递到循环体来完成此操作:
for index, item in enumerate(l):
if index > 0:
previous_item = l[index - 1]
else:
previous_item = None
该函数是一个内置函数。表示为生成器函数:
def neighborhood(iterable):
iterator = iter(iterable)
prev_item = None
current_item = next(iterator) # throws StopIteration if empty.
for next_item in iterator:
yield (prev_item, current_item, next_item)
prev_item = current_item
current_item = next_item
yield (prev_item, current_item, None)
用法:
for prev,item,next in neighborhood(l):
print prev, item, next
在处理需要某些上下文的生成器时,我经常使用下面的实用程序函数在迭代器上提供滑动窗口视图:
import collections, itertools
def window(it, winsize, step=1):
"""Sliding window iterator."""
it=iter(it) # Ensure we have an iterator
l=collections.deque(itertools.islice(it, winsize))
while 1: # Continue till StopIteration gets raised.
yield tuple(l)
for i in range(step):
l.append(it.next())
l.popleft()
它将一次生成序列N个项目的视图,并将步骤切换到其他项目。例如
>>> list(window([1,2,3,4,5],3))
[(1, 2, 3), (2, 3, 4), (3, 4, 5)]
在前向/后向情况下使用时,如果您还需要在没有下一个或上一个值的情况下处理数字,则可能需要使用适当的值(如None)填充序列
l= range(10)
# Print adjacent numbers
for cur, next in window(l + [None] ,2):
if next is None: print "%d is the last number." % cur
else: print "%d is followed by %d" % (cur,next)
就在前面
你是说下面的,对吗
previous = None
for item in someList:
if item == target: break
previous = item
# previous is the item before the target
如果您想要n个以前的项目,可以使用大小为n的循环队列来完成
queue=[]
对于someList中的项目:
如果item==目标:中断
queue.append(项目)
如果len(queue)>n:queue.pop(0)
如果len(队列)
输出:
1
如果您要查找的项目是列表中的第一个项目,这将环绕并返回列表中的最后一个项目。换句话说,如果上面代码中的item==1:
将第三行更改为,则会导致打印3
从中检查活套实用程序。它在循环项周围提供一个包装器对象,该对象提供诸如previous、next、first、last等属性
看看looper类的示例,它非常简单。还有其他这样的循环助手,但我现在记不起其他的了
例如:
> easy_install Tempita
> python
>>> from tempita import looper
>>> for loop, i in looper([1, 2, 3]):
... print loop.previous, loop.item, loop.index, loop.next, loop.first, loop.last, loop.length, loop.odd, loop.even
...
None 1 0 2 True False 3 True 0
1 2 1 3 False False 3 False 1
2 3 2 None False True 3 True 0
虽然不是很像蟒蛇,但它很简单:
l=[1,2,3]
for index in range(len(l)):
if l[index]==2:
l[index-1]
要做的事情:保护边缘我知道这很旧,但为什么不直接使用枚举
l = ['adam', 'rick', 'morty', 'adam', 'billy', 'bob', 'wally', 'bob', 'jerry']
for i, item in enumerate(l):
if i == 0:
previous_item = None
else:
previous_item = l[i - 1]
if i == len(l) - 1:
next_item = None
else:
next_item = l[i + 1]
print('Previous Item:', previous_item)
print('Item:', item)
print('Next Item:', next_item)
print('')
pass
如果您运行此程序,您将看到它会捕获上一个和下一个项目,而不关心列表中的重复项目。如果您希望解决方案在iterables上运行,则有一个配方可以完全满足您的需要:
l = [1, 2, 3]
for i, j in zip(l, l[1:]):
print(i, j)
我知道这是一个老问题,但我发现展示一个简单的解决方案很重要,这个解决方案也适用于生成器和其他类型的iterables,而不像大多数答案只适用于类似列表的对象。这与Brian的答案和这里的解决方案有些相似:
或者,在第二个iterable上调用next
(如果您确定它至少有一个元素):
在这种情况下,我可能会执行“prev,item=item,next”。要无限地进行此循环(无停止迭代),请执行itertools import cycle中的,并将第二行更改为:iterator=cycle(iterable)
在这种上下文中使用enumerate是否不太像Pythonic?您要寻找的答案是Vicky Liau的,在这一行下面的一行。或者,如果您想让它在任何iterable上工作,而不仅仅是列表/元组/字符串等,只需对zip中的prev、cur、nxt执行(l,l[1:],l[2:]):
,而不是所有这些代码。如果您需要在第一次和最后一次迭代中将prev
和nxt
设置为None
,只需在for
循环之前执行l=[None,*l,None]
?这很好,不涉及外部库或特殊函数。如果一个项目重复,这不是工作不正常吗<代码>[1,2,1,3]
?@Teepeemm,是的,我会用一个符合要求的版本来更新它。我使用了这个,但扩展了以避免删除开始/结束项:对于prev,cur,下一个在zip中([None]+l[:-1],l,l[1:+[None]):
您可以避免像这样删除开始/结束项:l=[None,*l,None]
然后对于prev,cur,nxt-in-zip(l,l[1:],l[2:]):
链接全部断开。如果您的列表只有一个元素长l=[2]
,这将返回与前一个元素相同的元素。如果您使用itertools
,请使用Francisco Couzo的答案:这与@Rudiger Wolf的答案完全相同
l = ['adam', 'rick', 'morty', 'adam', 'billy', 'bob', 'wally', 'bob', 'jerry']
for i, item in enumerate(l):
if i == 0:
previous_item = None
else:
previous_item = l[i - 1]
if i == len(l) - 1:
next_item = None
else:
next_item = l[i + 1]
print('Previous Item:', previous_item)
print('Item:', item)
print('Next Item:', next_item)
print('')
pass
l = [1, 2, 3]
for i, j in zip(l, l[1:]):
print(i, j)
import itertools
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
import itertools
iter0, iter1 = itertools.tee(iterable)
for item, next_item in itertools.zip_longest(
iter0,
itertools.islice(iter1, 1, None)
):
do_something(item, next_item)
import itertools
iter0, iter1 = itertools.tee(iterable)
_ = next(iter1)
for item, next_item in itertools.zip_longest(iter0, iter1):
do_something(item, next_item)