a = [5, 66, 7, 8, 9, ...]
是否可以进行迭代而不是像这样写?
a[1] - a[0]
a[2] - a[1]
a[3] - a[2]
a[4] - a[3]
...
谢谢!
答案 0 :(得分:47)
使用range
完全没问题。然而,编程(如数学)是建立在抽象的基础上。连续对 [(x0,x1),(x1,x2),...,(xn-2,xn-1)] 被称为成对组合,请参阅例如recipe in the itertools docs。在工具集中使用此功能后,您可以编写:
for x, y in pairwise(xs):
print(y - x)
或者,作为生成器表达式:
consecutive_diffs = (y - x for (x, y) in pairwise(xs))
答案 1 :(得分:17)
对于python 2中的小列表或python 3中的任何列表,您可以使用
[x - y for x, y in zip(a[1:], a)]
对于更大的列表,您可能需要
import itertools as it
[x - y for x, y in it.izip(a[1:], a)]
如果您使用的是python 2
我会考虑将其写为生成器表达式而不是
(x - y for x, y in it.izip(a[1:], a))
这将避免一次性在内存中创建第二个列表,但您只能迭代一次。如果你只想迭代它一次,那么这是理想的,如果你以后决定需要随机或重复访问,这很容易改变。特别是如果您要进一步处理它以制作列表,那么最后一个选项是理想的。
更新
目前最快的方法是
import itertools as it
import operator as op
list(it.starmap(op.sub, it.izip(a[1:], a)))
$ python -mtimeit -s's = [1, 2]*10000' '[x - y for x, y in zip(s[1:], s)]'
100 loops, best of 3: 13.5 msec per loop
$ python -mtimeit -s'import itertools as it; s = [1, 2]*10000' '[x - y for x, y in it.izip(s[1:], s)]'
100 loops, best of 3: 8.4 msec per loop
$ python -mtimeit -s'import itertools as it; import operator as op; s = [1, 2]*10000' 'list(it.starmap(op.sub, it.izip(s[1:], s)))'
100 loops, best of 3: 6.38 msec per loop
答案 2 :(得分:5)
答案 3 :(得分:0)
以下是itertools reciepes的示例:
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
哪个不太可读。如果你喜欢更容易理解的东西 了解生成器如何工作,这里有一个更长的例子,结果相同:
def pairwise(it):
"""
Walk a list in overlapping pairs.
>>> list(pairwise([0, 1, 2, 3, 4, 5]))
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
"""
it = iter(it)
start = None
while True:
if not start:
start = next(it)
end = next(it)
yield start, end
start = end
答案 4 :(得分:0)
def pairwise(iterable):
i = iter(iterable)
while True:
yield next(i), next(i, '')
答案 5 :(得分:0)
我建议使用很棒的more_itertools库,它具有立即可用的pairwise function:
import more_itertools
for a, b in more_itertools.pairwise([1, 2, 3, 4, 5]):
print(a, b)
# 1 2
# 2 3
# 3 4
# 4 5
这将使您免于编写自己的(可能有错误的)实现的麻烦。例如,此页面上的大多数实现都无法正确处理带有空的Iterable的情况-生成器函数永远不应引发StopIteration
,此行为considered deprecated并在Python 3.6中引起DeprecationWarning。它根本无法在Python 3.7中使用。