列表或元组的成对遍历

27 投票
6 回答
32427 浏览
提问于 2025-04-16 04:55
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

当然可以。

for i in range(1, len(a)):
    print a[i] - a[i-1]

我不太明白这里真正的问题是什么。你有没有看过这个Python教程

撰写回答