给定一个数字列表,我试图编写一个代码来找出连续元素之间的差异。例如,A = [1, 10, 100, 50, 40]
因此函数的输出应为[0, 9, 90, 50, 10]
。这是我到目前为止尝试使用递归的方法:
def deviation(A):
if len(A) < 2:
return
else:
return [abs(A[0]-A[1])] + [deviation(A[1: ])]
然而,我得到的输出(使用上面的A作为输入的例子)是[9, [90, [50, [10, None]]]]
。如何正确格式化括号? (我已经尝试过猜测和检查,但我这是我得到的最接近的)我怎么写它从前一个元素中减去当前元素而不会得到第一个元素的索引错误?我仍然希望输出列表的第一个元素为零,但我不知道如何使用递归进行此操作,并且出于某种原因,这似乎是我的最佳途径。
答案 0 :(得分:5)
你可以这样做:
[y-x for x, y in zip(A[:-1], A[1:])]
>>> A = [1, 10, 100, 50, 40]
>>> [y-x for x, y in zip(A[:-1], A[1:])]
[9, 90, -50, -10]
请注意,如果右侧较小,差异将是负数,您可以轻松解决此问题(如果您认为这是错误的),我将为您留下解决方案。
说明:
您可以获得的最佳解释是打印列表理解的每个部分。
A[:-1]
返回没有最后一个元素的列表:[1, 10, 100, 50]
A[1:]
返回没有第一个元素的列表:[10, 100, 50, 40]
zip(A[:-1], A[1:])
返回[(1, 10), (10, 100), (100, 50), (50, 40)]
答案 1 :(得分:4)
最简单(最懒惰)的解决方案是使用numpy函数diff:
>>> A = [1, 10, 100, 50, 40]
>>> np.diff(A)
array([ 9, 90, -50, -10])
如果您想要差异的绝对值(正如您的问题所隐含的那样),那么请获取数组的绝对值。
答案 2 :(得分:2)
[abs(j-A[i+1]) for i,j in enumerate(A[:-1])]
答案 3 :(得分:1)
实际上递归是一种矫枉过正的行为:
def deviation(A):
yield 0
for i in range(len(A) - 1):
yield abs(A[i+1] - A[i])
示例:
>>> A = [3, 5, 2]
>>> list(deviation(A))
[0, 2, 3]
编辑:然而,另一个更简单,更有效的解决方案就是:
def deviation(A):
prev = A[0]
for el in A:
yield abs(el - prev)
prev = el
答案 4 :(得分:1)
你可以做一个列表理解:
>>> A = [1, 10, 100, 50, 40]
>>> l=[A[0]]+A
>>> [abs(l[i-1]-l[i]) for i in range(1,len(l))]
[0, 9, 90, 50, 10]
答案 5 :(得分:1)
对于更长的递归解决方案,更符合您的原始方法:
def deviation(A) :
if len(A) < 2 :
return []
else :
return [abs(A[0]-A[1])] + deviation(A[1:])
您的括号问题与您的递归通话有关。由于您在[deviation(a[1: ])]
括号中有[]
,因此每次递归调用都会创建一个新列表,从而导致列表中有许多列表。
要解决None
问题,只需将基本案例更改为空列表[]
即可。现在,您的函数将在递归制作列表的末尾添加“无”,而不是带有空白None
'的固有return