Finding the difference between consecutive numbers

2019-05-09 02:07发布

Given a list of numbers, I am trying to write a code that finds the difference between consecutive elements. For instance, A = [1, 10, 100, 50, 40] so the output of the function should be [0, 9, 90, 50, 10]. Here is what I have so far trying to use recursion:

def deviation(A):
    if len(A) < 2:
        return
    else:
        return [abs(A[0]-A[1])] + [deviation(A[1: ])]

The output I get, however, (using the above example of A as the input) is [9, [90, [50, [10, None]]]]. How do I properly format my brackets? (I've tried guessing and checking but I this is the closest I have gotten) And how do I write this where it subtracts the current element from the previous element without getting an index error for the first element? I still want the first element of the output list to be zero but I do not know how to go about this using recursion and for some reason that seems the best route to me.

6条回答
劳资没心,怎么记你
2楼-- · 2019-05-09 02:21

Actually recursion is an overkill:

def deviation(A):
    yield 0
    for i in range(len(A) - 1):
        yield abs(A[i+1] - A[i])

Example:

>>> A = [3, 5, 2]
>>> list(deviation(A))
[0, 2, 3]

EDIT: Yet, another, even simplier and more efficient solution would be this:

def deviation(A):
    prev = A[0]
    for el in A:
        yield abs(el - prev)
        prev = el
查看更多
Deceive 欺骗
3楼-- · 2019-05-09 02:29

You can do:

[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]

Note that the difference will be negative if the right side is smaller, you can easily fix this (If you consider this wrong), I'll leave the solution for you.

Explanation:

The best explanation you can get is simply printing each part of the list comprehension.

  • A[:-1] returns the list without the last element: [1, 10, 100, 50]
  • A[1:] returns the list without the first element: [10, 100, 50, 40]
  • zip(A[:-1], A[1:]) returns [(1, 10), (10, 100), (100, 50), (50, 40)]
  • The last step is simply returning the difference in each tuple.
查看更多
地球回转人心会变
4楼-- · 2019-05-09 02:30

You can do a list comprehension:

>>> 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]
查看更多
倾城 Initia
5楼-- · 2019-05-09 02:30

For a longer recursive solution more in line with your original approach:

def deviation(A) :
    if len(A) < 2 :
        return []
    else :
        return [abs(A[0]-A[1])] + deviation(A[1:])

Your bracket issue is with your recursive call. Since you have your [deviation(a[1: ])] in its own [] brackets, with every recursive call you're going to be creating a new list, resulting in your many lists within lists.

In order to fix the None issue, just change your base case to an empty list []. Now your function will add 'nothing' to the end of your recursively made list, as opposed to the inherent None that comes with a blank return'

查看更多
来,给爷笑一个
6楼-- · 2019-05-09 02:31

The simplest (laziest) solution is to use the numpy function diff:

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

If you want the absolute value of the differences (as you've implied by your question), then take the absolute value of the array.

查看更多
一纸荒年 Trace。
7楼-- · 2019-05-09 02:31
[abs(j-A[i+1]) for i,j in enumerate(A[:-1])]
查看更多
登录 后发表回答