到目前为止,解决方案只处理列表,而且大多数都在复制列表。在我的经验中,很多时候这是不可能的。
而且,它们不处理列表中可以有重复元素的事实。
你问题的题目是“循环中的前一个和下一个值。“,但是如果在循环中运行大多数答案,那么最终会在每个元素上迭代整个列表以找到它。
所以我刚刚创建了一个函数,使用itertools模块,拆分并分割可迭代的元素,并与前面的元素和下一个元素一起生成元组。并不完全是你的代码所做的,但值得一看,因为它可能解决你的问题。from itertools import tee, islice, chain, izip
def previous_and_next(some_iterable):
prevs, items, nexts = tee(some_iterable, 3)
prevs = chain([None], prevs)
nexts = chain(islice(nexts, 1, None), [None])
return izip(prevs, items, nexts)
然后在循环中使用它,将在循环中包含前一项和下一项:mylist = ['banana', 'orange', 'apple', 'kiwi', 'tomato']
for previous, item, nxt in previous_and_next(mylist):
print "Item is now", item, "next is", nxt, "previous is", previous
结果:Item is now banana next is orange previous is None
Item is now orange next is apple previous is banana
Item is now apple next is kiwi previous is orange
Item is now kiwi next is tomato previous is apple
Item is now tomato next is None previous is kiwi
它可以处理任意大小的列表(因为它不复制列表),以及任何可迭代的(文件、集等)。这样,您就可以在序列上进行迭代,并在循环中获得以前的和下一个可用的项。不需要在序列中再次搜索项目。
对守则的简短解释:tee用于在输入序列上有效地创建3个独立的迭代器。
chain将两个序列链接为一个;它在这里用于追加一个元素序列。[None]到prevs
islice用于生成除第一个元素之外的所有元素的序列,然后chain用于追加None到最后
现在有3个独立的序列基于some_iterable看起来像:prevs:None, A, B, C, D, E
items:A, B, C, D, E
nexts:B, C, D, E, None
最后izip用于将3个序列转换为一个三重态序列。
请注意izip当任何输入序列耗尽时停止,因此prevs将被忽略,这是正确的-没有这样的元素,最后一个元素将是它的prev...。我们可以把最后的元素从prevs但izip他的行为使这件事变得多余
还请注意tee,,,izip,,,islice和chain从itertools模块;它们对输入序列进行动态操作(懒惰),这使得它们高效,并且不需要在任何时候将整个序列同时存储在内存中。
在python 3,它将在导入时显示一个错误。izip,你可以用zip而不是izip...。不需要进口zip中预先定义的python 3-