Given a list of numbers how to find differences between every (i
)-th and (i+1
)-th of its elements? Should one better use lambda or maybe lists comprehension?
给定一个数字列表,如何找出每个(i)-th和(i+1)-th元素之间的差异?应该使用lambda还是列表理解?
Example: Given a list t=[1,3,6,...]
it is to find a list v=[2,3,...]
because 3-1=2
, 6-3=3
, etc.
例:给定一个列表t=[1,3,6,…]是查找列表v=[2,3,……因为3-1=2,6-3=3,等等。
7 个解决方案
#1
104
>>> t
[1, 3, 6]
>>> [j-i for i, j in zip(t[:-1], t[1:])] # or use itertools.izip in py2k
[2, 3]
#2
71
The other answers are correct but if you're doing numerical work, you might want to consider numpy. Using numpy, the answer is:
其他的答案是正确的,但是如果你做数值计算,你可能想考虑numpy。使用numpy,答案是:
v = numpy.diff(t)
#3
25
If you don't want to use numpy
nor zip
, you can use the simple (simplest in my opinion) solution:
如果你不想使用numpy或zip,你可以使用简单的(在我看来最简单的)解决方案:
>>> t = [1, 3, 6]
>>> v = [t[i+1]-t[i] for i in range(len(t)-1)]
>>> v
[2, 3]
#4
8
You can use itertools.tee
and zip
to efficiently build the result:
出现您可以使用itertools。tee和zip有效地构建结果:
from itertools import tee
# python2 only:
#from itertools import izip as zip
def differences(seq):
iterable, copied = tee(seq)
next(copied)
for x, y in zip(iterable, copied):
yield y - x
Or using itertools.islice
instead:
出现或使用itertools。islice相反:
from itertools import islice
def differences(seq):
nexts = islice(seq, 1, None)
for x, y in zip(seq, nexts):
yield y - x
You can also avoid using the itertools
module:
您还可以避免使用itertools模块:
def differences(seq):
iterable = iter(seq)
prev = next(iterable)
for element in iterable:
yield element - prev
prev = element
All these solution work in constant space if you don't need to store all the results and support infinite iterables.
如果不需要存储所有结果并支持无限的可迭代性,那么所有这些解决方案都可以在常量空间中工作。
Here are some micro-benchmarks of the solutions:
以下是解决方案的一些微观基准:
In [12]: L = range(10**6)
In [13]: from collections import deque
In [15]: %timeit deque(differences_tee(L), maxlen=0)
10 loops, best of 3: 122 ms per loop
In [16]: %timeit deque(differences_islice(L), maxlen=0)
10 loops, best of 3: 127 ms per loop
In [17]: %timeit deque(differences_no_it(L), maxlen=0)
10 loops, best of 3: 89.9 ms per loop
And the other proposed solutions:
及其他建议的解决方案:
In [18]: %timeit [x[1] - x[0] for x in zip(L[1:], L)]
10 loops, best of 3: 163 ms per loop
In [19]: %timeit [L[i+1]-L[i] for i in range(len(L)-1)]
1 loops, best of 3: 395 ms per loop
In [20]: import numpy as np
In [21]: %timeit np.diff(L)
1 loops, best of 3: 479 ms per loop
In [35]: %%timeit
...: res = []
...: for i in range(len(L) - 1):
...: res.append(L[i+1] - L[i])
...:
1 loops, best of 3: 234 ms per loop
Note that:
注意:
-
zip(L[1:], L)
is equivalent tozip(L[1:], L[:-1])
sincezip
already terminates on the shortest input, however it avoids a whole copy ofL
. - zip(L[1:], L)等价于zip(L[1:], L[:-1]),因为zip已经终止于最短的输入,但是它避免了L的整个拷贝。
- Accessing the single elements by index is very slow because every index access is a method call in python
- 通过索引访问单个元素非常缓慢,因为在python中,每个索引访问都是一个方法调用
-
numpy.diff
is slow because it has to first convert thelist
to andarray
. Obviously if you start with anndarray
it will be much faster:numpy。diff很慢,因为它必须首先将列表转换为ndarray。显然,如果你从ndarray开始,它会快得多:
In [22]: arr = np.array(L) In [23]: %timeit np.diff(arr) 100 loops, best of 3: 3.02 ms per loop
#5
3
Ok. I think I found the proper solution:
好的。我认为我找到了合适的解决办法:
v = [x[1]-x[0] for x in zip(t[1:],t[:-1])]
#6
3
A functional approach:
功能的方法:
>>> import operator
>>> a = [1,3,5,7,11,13,17,21]
>>> map(operator.sub, a[1:], a[:-1])
[2, 2, 2, 4, 2, 4, 4]
Using generator:
使用发电机:
>>> import operator, itertools
>>> g1,g2 = itertools.tee((x*x for x in xrange(5)),2)
>>> list(itertools.imap(operator.sub, itertools.islice(g1,1,None), g2))
[1, 3, 5, 7]
Using indices:
使用指数:
>>> [a[i+1]-a[i] for i in xrange(len(a)-1)]
[2, 2, 2, 4, 2, 4, 4]
#7
-1
My way
我的方式
>>>v = [1,2,3,4,5]
>>>[v[i] - v[i-1] for i, value in enumerate(v[1:], 1)]
[1, 1, 1, 1]
#1
104
>>> t
[1, 3, 6]
>>> [j-i for i, j in zip(t[:-1], t[1:])] # or use itertools.izip in py2k
[2, 3]
#2
71
The other answers are correct but if you're doing numerical work, you might want to consider numpy. Using numpy, the answer is:
其他的答案是正确的,但是如果你做数值计算,你可能想考虑numpy。使用numpy,答案是:
v = numpy.diff(t)
#3
25
If you don't want to use numpy
nor zip
, you can use the simple (simplest in my opinion) solution:
如果你不想使用numpy或zip,你可以使用简单的(在我看来最简单的)解决方案:
>>> t = [1, 3, 6]
>>> v = [t[i+1]-t[i] for i in range(len(t)-1)]
>>> v
[2, 3]
#4
8
You can use itertools.tee
and zip
to efficiently build the result:
出现您可以使用itertools。tee和zip有效地构建结果:
from itertools import tee
# python2 only:
#from itertools import izip as zip
def differences(seq):
iterable, copied = tee(seq)
next(copied)
for x, y in zip(iterable, copied):
yield y - x
Or using itertools.islice
instead:
出现或使用itertools。islice相反:
from itertools import islice
def differences(seq):
nexts = islice(seq, 1, None)
for x, y in zip(seq, nexts):
yield y - x
You can also avoid using the itertools
module:
您还可以避免使用itertools模块:
def differences(seq):
iterable = iter(seq)
prev = next(iterable)
for element in iterable:
yield element - prev
prev = element
All these solution work in constant space if you don't need to store all the results and support infinite iterables.
如果不需要存储所有结果并支持无限的可迭代性,那么所有这些解决方案都可以在常量空间中工作。
Here are some micro-benchmarks of the solutions:
以下是解决方案的一些微观基准:
In [12]: L = range(10**6)
In [13]: from collections import deque
In [15]: %timeit deque(differences_tee(L), maxlen=0)
10 loops, best of 3: 122 ms per loop
In [16]: %timeit deque(differences_islice(L), maxlen=0)
10 loops, best of 3: 127 ms per loop
In [17]: %timeit deque(differences_no_it(L), maxlen=0)
10 loops, best of 3: 89.9 ms per loop
And the other proposed solutions:
及其他建议的解决方案:
In [18]: %timeit [x[1] - x[0] for x in zip(L[1:], L)]
10 loops, best of 3: 163 ms per loop
In [19]: %timeit [L[i+1]-L[i] for i in range(len(L)-1)]
1 loops, best of 3: 395 ms per loop
In [20]: import numpy as np
In [21]: %timeit np.diff(L)
1 loops, best of 3: 479 ms per loop
In [35]: %%timeit
...: res = []
...: for i in range(len(L) - 1):
...: res.append(L[i+1] - L[i])
...:
1 loops, best of 3: 234 ms per loop
Note that:
注意:
-
zip(L[1:], L)
is equivalent tozip(L[1:], L[:-1])
sincezip
already terminates on the shortest input, however it avoids a whole copy ofL
. - zip(L[1:], L)等价于zip(L[1:], L[:-1]),因为zip已经终止于最短的输入,但是它避免了L的整个拷贝。
- Accessing the single elements by index is very slow because every index access is a method call in python
- 通过索引访问单个元素非常缓慢,因为在python中,每个索引访问都是一个方法调用
-
numpy.diff
is slow because it has to first convert thelist
to andarray
. Obviously if you start with anndarray
it will be much faster:numpy。diff很慢,因为它必须首先将列表转换为ndarray。显然,如果你从ndarray开始,它会快得多:
In [22]: arr = np.array(L) In [23]: %timeit np.diff(arr) 100 loops, best of 3: 3.02 ms per loop
#5
3
Ok. I think I found the proper solution:
好的。我认为我找到了合适的解决办法:
v = [x[1]-x[0] for x in zip(t[1:],t[:-1])]
#6
3
A functional approach:
功能的方法:
>>> import operator
>>> a = [1,3,5,7,11,13,17,21]
>>> map(operator.sub, a[1:], a[:-1])
[2, 2, 2, 4, 2, 4, 4]
Using generator:
使用发电机:
>>> import operator, itertools
>>> g1,g2 = itertools.tee((x*x for x in xrange(5)),2)
>>> list(itertools.imap(operator.sub, itertools.islice(g1,1,None), g2))
[1, 3, 5, 7]
Using indices:
使用指数:
>>> [a[i+1]-a[i] for i in xrange(len(a)-1)]
[2, 2, 2, 4, 2, 4, 4]
#7
-1
My way
我的方式
>>>v = [1,2,3,4,5]
>>>[v[i] - v[i-1] for i, value in enumerate(v[1:], 1)]
[1, 1, 1, 1]