在python中使用lambda函数创建diff数组

在python中使用lambda函数创建diff数组,python,python-2.7,lambda,Python,Python 2.7,Lambda,我希望在python中创建一个diff数组,如下所示 >>> a = [1,5,3,8,2,4,7,6] >>> diff = [] >>> a = sorted(a,reverse=True) >>> for i in xrange(len(a)-1): diff.append(a[i]-a[i+1]) 但是我想重构上面的代码。我尝试使用lambda函数实现它。但是没有得到结果 >>>

我希望在python中创建一个diff数组,如下所示

>>> a = [1,5,3,8,2,4,7,6]
>>> diff = []
>>> a = sorted(a,reverse=True)
>>> for i in xrange(len(a)-1):
        diff.append(a[i]-a[i+1])
但是我想重构上面的代码。我尝试使用lambda函数实现它。但是没有得到结果

>>> [i for i in lambda x,y:y-x,sorted(a,reverse=True)]
上面的代码返回

[<function <lambda> at 0x00000000023B9C18>, [1, 2, 3, 4, 5, 6, 7, 8]]
[,[1,2,3,4,5,6,7,8]]
我想知道是否可以使用lambda函数或任何其他技术实现所需的功能? 提前感谢您的帮助

注:

1) 数组“a”可能很大。为了举例,我使用了一个小数组


2) 结果必须在最短时间内完成。

您可以使用列表理解,如下所示:

>>> a = sorted([1,5,3,8,2,4,7,6], reverse=True)
>>> diff = [a[i]-a[i+1] for i in xrange(len(a)-1)]
>>> diff
[1, 1, 1, 1, 1, 1, 1]
>>> 
diff = [v[0] - v[1] for v in zip(sorted(a,reverse=True)[0:-1], sorted(a,reverse=True)[1:])]

#gives: diff = [1, 1, 1, 1, 1, 1, 1]
你说的,或者其他任何技巧,所以我认为这是有效的。但是,我还没有找到一个有效的
lambda
解决方案:)

将此答案的时间与以下所有内容进行比较: 我的:

1.59740447998e-05秒

@Marcin's

0.00110197067261秒

@roippi's

0.000382900238037

@二战的

0.00154685974121

因此,我的速度显然是最快的超过两倍,其次是@roippi,其次是@Marcin,最后是@wwi


另外,我在这里完全没有偏见,我的计时方法是使用当前的
time.time()

>>> a = sorted([1,5,3,8,2,4,7,6], reverse=True)
>>> diff = [a[i]-a[i+1] for i in xrange(len(a)-1)]
>>> diff
[1, 1, 1, 1, 1, 1, 1]
>>> 
diff = [v[0] - v[1] for v in zip(sorted(a,reverse=True)[0:-1], sorted(a,reverse=True)[1:])]

#gives: diff = [1, 1, 1, 1, 1, 1, 1]
虽然这里你用了两次排序。不确定这对你是否重要

正如@aj8uppal所建议的,在之前最好有一个按排序的版本,因此在本例中,您可以:

a = sorted([1,5,3,8,2,4,7,6], reverse=True)
diff = [v[0] - v[1] for v in zip(a[0:-1], a[1:])]    
#gives: diff = [1, 1, 1, 1, 1, 1, 1]
无法真正改善这些线路。您需要通过对数据进行排序来转换数据,而无需更改您所做的工作

from itertools import izip, starmap

from operator import sub

list(starmap(sub,izip(a,a[1:])))
Out[12]: [1, 1, 1, 1, 1, 1, 1]
如果
a
非常大,可以用
islice
替换
a[1:][/code>片以节省内存开销:

list(starmap(sub,izip(a,islice(a,1,None))))
尽管如此,如果它真的那么大,你还是应该使用
numpy

np.diff(a) * -1
Out[24]: array([1, 1, 1, 1, 1, 1, 1])
如果您可以使用:

如果需要对数据进行排序,则与十万个随机整数进行定时比较-numpy会更快:

from timeit import Timer
a = [random.randint(0, 1000000) for _ in xrange(100000)]
##print a[:100]
def foo(a):
    a = sorted(a, reverse=True)
    return [a[i]-a[i+1] for i in xrange(len(a)-1)]

def bar(a):
    return np.diff(np.sort(a))

t = Timer('foo(a)', 'from __main__ import foo, bar, np, a')
print t.timeit(10)
# 0.86916993838

t = Timer('bar(a)', 'from __main__ import foo, bar, np, a')
print t.timeit(10)
# 0.28586356791

这似乎是让代码成为一行代码不值得的情况之一。这比双线解决方案(imo)可读性差得多,需要排序
a
两次。@dano这是一种可能的解决方案。也许不是最优的,但它能满足OP的要求。数组“a”可能很大,时间复杂度是一个优先考虑的问题。此解决方案可能无法满足要求。我会相应地编辑问题陈述。@Marcin我建议将
a
定义为
sorted([1,5,3,8,2,4,7,6],reverse=True)
这样你就不必写
sorted(a,reverse=True)
两次,你只需说
a
@aj8uppal-Thx即可。如果不进行两次排序,我就找不到在列表理解中保持排序的方法。我试着给出答案,在列表理解之前进行排序。列表理解的另一种实现方式是:
diff=v-a[I+1]for I,v in enumerate(a[:-1])]
如果你在一个大小合理的列表(比如10k个元素)上进行基准测试,你的函数将不会是最快的。另外,你应该使用一个真正的测试夹具(比如
timeit
),而不是用
time
滚动你自己的夹具。我用5000个随机选取的元素测试了我的夹具。使用
range(100000)
,这个listcomp仍然比转换成numpy数组然后进行区分快。如果对象已经是
ndarray
numpy.diff
的排序速度大约是100k elementsThrow的40倍(
np.sort
用于ndarray),并且它们是可比的-listcomp仍然快10%左右。您真的需要/想要在计算之前对数据进行排序吗?将
a
作为输入的期望结果是什么?只有在对数组进行排序后,才能计算Diff数组。