Detect Alternating Signs
Is there a nice and short way to tell whether a python list (or numpy array) contains numbers with alternating signs? In other words: is_alternating_signs([1, -1, 1, -1, 1]) == Tru
Solution 1:
OK, thanks to SO "related" feature. I found this question and adopted the answer by ianalis and the comment by lazyr
def is_alternating_signs(a):
return numpy.all(numpy.abs(numpy.diff(numpy.sign(a))) == 2)
print is_alternating_signs([1, -1, 1, -1, 1])
print is_alternating_signs([-1, 1, -1, 1, -1])
print is_alternating_signs([1, -1, 1, -1, -1])
The output is
TrueTrueFalse
Solution 2:
You could check every even member is negative and every odd member is positive by taking a slice of every second item, starting at either the beginning or from position one. Also test the reverse to cover both possibilities.
so:
defis_alternating_signs(l):
return ( (all(x<0for x in l[::2]) andall(x>=0for x in l[1::2])) or
(all(x>=0for x in l[::2]) andall(x<0for x in l[1::2])))
Solution 3:
Using decimal module and is_signed method:
from decimal import Decimal
a = [1, -1, 1, -1, 1]
b = [-1, 1, -1, 1, -1]
c = [1, -1, 1, -1, -1]
def is_alternating_signs(values):
lVals = [Decimal(val).is_signed() forvalin values]
prevVal = lVals.pop(0)
forvalin lVals:
if prevVal == val:
return False
prevVal = valreturn True
is_alternating_signs(a)
is_alternating_signs(b)
is_alternating_signs(c)
Solution 4:
I like pairwise:
from itertools import izip, tee
defpairwise(iterable):
a, b = tee(iterable)
next(b)
return izip(a, b)
defis_alternating_signs(iterable):
returnall(x < 0 < y or x > 0 > y for x, y in pairwise(iterable))
If there are no zeros in iterable
this also works:
defis_alternating_signs(iterable):
returnall((x < 0) == (0 < y) for x, y in pairwise(iterable))
Solution 5:
how about something like...
defis_alternating_signs(aList):
returnall( (aList[i]^aList[i-1])<0for i inrange(1,len(aList)) )
Post a Comment for "Detect Alternating Signs"