在列表中查找连续数字的差值(Python)

8 投票
6 回答
15406 浏览
提问于 2025-04-18 12:22

给定一个数字列表,我想写一段代码来找出连续元素之间的差值。比如说,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: ])]

不过,我得到的输出是[9, [90, [50, [10, None]]]](用上面的例子A作为输入)。我该如何正确地格式化我的括号呢?(我试过猜测和检查,但这是我目前得到的最接近的结果)另外,我该如何写这段代码,让它在不出现索引错误的情况下,从当前元素中减去前一个元素?我还是想让输出列表的第一个元素为零,但我不知道如何用递归来实现这个,感觉这似乎是最好的方法。

6 个回答

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
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 会返回这个值。

2

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。比如说,当你在写代码时,可能会发现某个功能没有按照预期工作。这种时候,很多人会去问其他人,看看有没有人遇到过类似的问题。

StackOverflow就是一个这样的地方,大家可以在这里提问和回答问题。你可以把它想象成一个大型的问答社区,专门为程序员提供帮助。在这里,你可以找到很多关于编程的知识和技巧,也能看到别人是如何解决问题的。

当你在StackOverflow上提问时,记得描述清楚你的问题,包括你遇到的错误信息、你使用的代码,以及你希望实现的目标。这样,其他人才能更好地理解你的问题,并给出有效的建议。

总之,StackOverflow是一个很有用的资源,适合所有想要学习编程的人。无论你是新手还是有经验的开发者,都能在这里找到帮助和灵感。

[abs(j-A[i+1]) for i,j in enumerate(A[:-1])]
7

最简单(也是最懒)的解决办法就是用numpy里的diff函数:

>>> A = [1, 10, 100, 50, 40]
>>> np.diff(A)
array([  9,  90, -50, -10])

如果你想要差值的绝对值(就像你问题里提到的那样),那么就对数组取绝对值。

13

你可以这样做:

[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)]
  • 最后一步就是返回每个元组中的差值。

撰写回答