Is there a way to access a list(or tuple, or other iterable)'s next, or previous element while looping through with for loop?
有没有办法在循环使用for循环时访问列表(或元组,或其他可迭代)的下一个或前一个元素?
l=[1,2,3]
for item in l:
if item==2:
get_previous(l,item)
12 个解决方案
#1
63
Expressed as a generator function:
表示为生成器函数:
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)
Usage:
用法:
for prev,item,next in neighborhood(l):
print prev, item, next
#2
22
One simple way.
一个简单的方法。
l=[1,2,3]
for i,j in zip(l, l[1:]):
print i, j
#3
10
l=[1,2,3]
for i,item in enumerate(l):
if item==2:
get_previous=l[i-1]
print get_previous
>>>1
#4
6
When dealing with generators where you need some context, I often use the below utility function to give a sliding window view on an iterator:
在处理需要某些上下文的生成器时,我经常使用下面的实用程序函数在迭代器上给出一个滑动窗口视图:
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()
It'll generate a view of the sequence N items at a time, shifting step places over. eg.
它将一次生成序列N个项目的视图,将步骤移位。例如。
>>> list(window([1,2,3,4,5],3))
[(1, 2, 3), (2, 3, 4), (3, 4, 5)]
When using in lookahead/behind situations where you also need to deal with numbers without having a next or previous value, you may want pad the sequence with an appropriate value such as 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)
#5
5
Check out the looper utility from the Tempita project. It gives you a wrapper object around the loop item that provides properties such as previous, next, first, last etc.
查看Tempita项目中的looper实用程序。它为循环项提供了一个包装器对象,它提供了上一个,下一个,第一个,最后一个等属性。
Take a look at the source code for the looper class, it is quite simple. There are other such loop helpers out there, but I cannot remember any others right now.
看一下looper类的源代码,很简单。还有其他这样的循环助手,但我现在不记得其他任何人。
Example:
例:
> 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
#6
5
I know this is old, but why not just use enumerate
?
我知道这是旧的,但为什么不使用枚举?
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
If you run this you will see that it grabs previous and next items and doesn't care about repeating items in the list.
如果你运行它,你会看到它抓住上一个和下一个项目,而不关心重复列表中的项目。
#7
1
I don't think there is a straightforward way, especially that an iterable can be a generator (no going back). There's a decent workaround, relying on explicitly passing the index into the loop body:
我不认为有一种直截了当的方式,尤其是可迭代可以是一个生成器(不会回头)。有一个不错的解决方法,依赖于显式将索引传递给循环体:
for itemIndex, item in enumerate(l):
if itemIndex>0:
previousItem = l[itemIndex-1]
else:
previousItem = None
The enumerate()
function is a builtin.
enumerate()函数是内置函数。
#8
0
Iterators only have the next() method so you cannot look forwards or backwards, you can only get the next item.
迭代器只有next()方法,所以你不能向前或向后看,你只能得到下一个项目。
enumerate(iterable) can be useful if you are iterating a list or tuple.
如果要迭代列表或元组,则枚举(可迭代)可能很有用。
#9
0
Immediately previous?
马上以前?
You mean the following, right?
你的意思是以下,对吗?
previous = None
for item in someList:
if item == target: break
previous = item
# previous is the item before the target
If you want n previous items, you can do this with a kind of circular queue of size n.
如果你想要n个先前的项目,你可以用一种大小为n的循环队列来做到这一点。
queue = []
for item in someList:
if item == target: break
queue .append( item )
if len(queue ) > n: queue .pop(0)
if len(queue ) < n: previous = None
previous = previous[0]
# previous is *n* before the target
#10
0
If you want the solution to work on iterables, the itertools' docs has a recipe that does exactly what you want:
如果您希望解决方案能够处理迭代,那么itertools的文档会有一个完全符合您需求的配方:
import itertools
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
If you're using Python 2.x, use itertools.izip
instead of zip
如果您使用的是Python 2.x,请使用itertools.izip而不是zip
#11
-2
Not very pythonic, but gets it done and is simple:
不是非常pythonic,但完成它并且很简单:
l=[1,2,3]
for index in range(len(l)):
if l[index]==2:
l[index-1]
TO DO: protect the edges
要做的事:保护边缘
#12
-7
The most simple way is to search the list for the item:
最简单的方法是在列表中搜索项目:
def get_previous(l, item):
idx = l.find(item)
return None if idx == 0 else l[idx-1]
Of course, this only works if the list only contains unique items. The other solution is:
当然,这仅在列表仅包含唯一项目时才有效。另一个解决方案是:
for idx in range(len(l)):
item = l[idx]
if item == 2:
l[idx-1]
#1
63
Expressed as a generator function:
表示为生成器函数:
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)
Usage:
用法:
for prev,item,next in neighborhood(l):
print prev, item, next
#2
22
One simple way.
一个简单的方法。
l=[1,2,3]
for i,j in zip(l, l[1:]):
print i, j
#3
10
l=[1,2,3]
for i,item in enumerate(l):
if item==2:
get_previous=l[i-1]
print get_previous
>>>1
#4
6
When dealing with generators where you need some context, I often use the below utility function to give a sliding window view on an iterator:
在处理需要某些上下文的生成器时,我经常使用下面的实用程序函数在迭代器上给出一个滑动窗口视图:
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()
It'll generate a view of the sequence N items at a time, shifting step places over. eg.
它将一次生成序列N个项目的视图,将步骤移位。例如。
>>> list(window([1,2,3,4,5],3))
[(1, 2, 3), (2, 3, 4), (3, 4, 5)]
When using in lookahead/behind situations where you also need to deal with numbers without having a next or previous value, you may want pad the sequence with an appropriate value such as 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)
#5
5
Check out the looper utility from the Tempita project. It gives you a wrapper object around the loop item that provides properties such as previous, next, first, last etc.
查看Tempita项目中的looper实用程序。它为循环项提供了一个包装器对象,它提供了上一个,下一个,第一个,最后一个等属性。
Take a look at the source code for the looper class, it is quite simple. There are other such loop helpers out there, but I cannot remember any others right now.
看一下looper类的源代码,很简单。还有其他这样的循环助手,但我现在不记得其他任何人。
Example:
例:
> 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
#6
5
I know this is old, but why not just use enumerate
?
我知道这是旧的,但为什么不使用枚举?
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
If you run this you will see that it grabs previous and next items and doesn't care about repeating items in the list.
如果你运行它,你会看到它抓住上一个和下一个项目,而不关心重复列表中的项目。
#7
1
I don't think there is a straightforward way, especially that an iterable can be a generator (no going back). There's a decent workaround, relying on explicitly passing the index into the loop body:
我不认为有一种直截了当的方式,尤其是可迭代可以是一个生成器(不会回头)。有一个不错的解决方法,依赖于显式将索引传递给循环体:
for itemIndex, item in enumerate(l):
if itemIndex>0:
previousItem = l[itemIndex-1]
else:
previousItem = None
The enumerate()
function is a builtin.
enumerate()函数是内置函数。
#8
0
Iterators only have the next() method so you cannot look forwards or backwards, you can only get the next item.
迭代器只有next()方法,所以你不能向前或向后看,你只能得到下一个项目。
enumerate(iterable) can be useful if you are iterating a list or tuple.
如果要迭代列表或元组,则枚举(可迭代)可能很有用。
#9
0
Immediately previous?
马上以前?
You mean the following, right?
你的意思是以下,对吗?
previous = None
for item in someList:
if item == target: break
previous = item
# previous is the item before the target
If you want n previous items, you can do this with a kind of circular queue of size n.
如果你想要n个先前的项目,你可以用一种大小为n的循环队列来做到这一点。
queue = []
for item in someList:
if item == target: break
queue .append( item )
if len(queue ) > n: queue .pop(0)
if len(queue ) < n: previous = None
previous = previous[0]
# previous is *n* before the target
#10
0
If you want the solution to work on iterables, the itertools' docs has a recipe that does exactly what you want:
如果您希望解决方案能够处理迭代,那么itertools的文档会有一个完全符合您需求的配方:
import itertools
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
If you're using Python 2.x, use itertools.izip
instead of zip
如果您使用的是Python 2.x,请使用itertools.izip而不是zip
#11
-2
Not very pythonic, but gets it done and is simple:
不是非常pythonic,但完成它并且很简单:
l=[1,2,3]
for index in range(len(l)):
if l[index]==2:
l[index-1]
TO DO: protect the edges
要做的事:保护边缘
#12
-7
The most simple way is to search the list for the item:
最简单的方法是在列表中搜索项目:
def get_previous(l, item):
idx = l.find(item)
return None if idx == 0 else l[idx-1]
Of course, this only works if the list only contains unique items. The other solution is:
当然,这仅在列表仅包含唯一项目时才有效。另一个解决方案是:
for idx in range(len(l)):
item = l[idx]
if item == 2:
l[idx-1]