4

i'm just wondering how I could check to verify that a list of numbers is arithmetic or not using python, so whether there is a common number in between each item in the list.

0

6 Answers 6

5

This is what I'd write:

all((i - j) == (j - k) for i, j, k in zip(l[:-2], l[1:-1], l[2:]))

You could probably make it more efficient by only computing the differences once, but if you're concerned about efficiency you'd use numpy and write:

np.all((a[:-2] - a[1:-1]) == (a[1:-1] - a[2:]))

or even (saving a slice):

np.all(a[:-2] + a[2:] == 2 * a[1:-1])

Probably the most concise method is to use numpy.diff, as it will automatically convert a list into a numpy array:

np.all(np.diff(l, 2) == 0)
Sign up to request clarification or add additional context in comments.

Comments

5

You can use numpy.diff if you have access to numpy:

>>> a = numpy.array(range(1, 15, 2))
>>> numpy.diff(a)
array([2, 2, 2, 2, 2, 2])

So you can do

>>> d = numpy.diff(a)
>>> not numpy.any(d-d[0])
True

or even better

>>> not numpy.any(numpy.diff(a, 2))
True

2 Comments

Like the higher order diff, I'd forgotten about that!
hey unfortunately I don't have access to numpy :( great answer though :)
1

If you mean an arithmetic sequence as in a series of numbers such that each number is simply the equal to the previous one plus some constant amount (like [1, 3, 5, 7] or [8, 18, 28, 38] but not [1, 2, 4, 8] or [1, 3, 1, 5, 1, 7]) then you probably shouldn't overthink it. It is unlikely that a list comprehension outperforms this:

def is_arithmetic(l):
    delta = l[1] - l[0]
    for index in range(len(l) - 1):
        if not (l[index + 1] - l[index] == delta):
             return False
    return True

1 Comment

A list comprehension would be worse, because it generates a list which is then thrown away (like your invocation of range). However, none of these answers are list comprehensions - they're generator comprehensions.
1

What about examining the length of the set of all differences in the list?

>>> alist = [3,9,15,21,27,33,39,45,51,57]
>>> blist = [-7, -2, 3, 8, 13, 18, 23, 29]
>>> 1 == len(set([alist[x + 1] - alist[x] for x in range(len(alist) - 1)]))
True
>>> 1 == len(set([blist[x + 1] - blist[x] for x in range(len(blist) - 1)]))
False
>>> 

Comments

1

Here's a solution that only calculates the difference once:

from itertools import izip

def is_arithmetic(seq):
    gen = (i - j for i, j in izip(seq[:-1], seq[1:]))
    diff = next(gen, None)  # get the first element in the generator
    return all(d == diff for d in gen) # check all the others are equal to it

Or more cryptically:

def is_arithmetic(seq):
    gen = (i - j for i, j in izip(seq[:-1], seq[1:]))
    return all(d == d0 for d in gen for d0 in gen)  # wat

Comments

0
def check_arith(lst):

    l1 = len(lst) - 1
    n= 2

    dif = lst[1] - lst[0]

    while(n<l1):

        if (lst[n+1] - lst[n]) != dif: 
            return False
        else:
            n = n + 1
    return True

print(check_arith([5,10,15, 20, 25]))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.