列表或元组的成对遍历
a = [5, 66, 7, 8, 9, ...]
有没有办法用循环来代替这样写呢?
a[1] - a[0]
a[2] - a[1]
a[3] - a[2]
a[4] - a[3]
...
谢谢你!
6 个回答
21
对于在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
65
使用 range
是可以的。不过,编程(就像数学一样)是关于建立在抽象概念上的。连续的成对组合,比如 [(x0, x1), (x1, x2), ..., (xn-2, xn-1)],被称为 成对组合。你可以在 itertools 文档 中看到一个例子。一旦你在工具箱里有了这个函数,你就可以这样写:
for x, y in pairwise(xs):
print(y - x)
或者可以作为生成器表达式使用:
consecutive_diffs = (y - x for (x, y) in pairwise(xs))
1