检测交替的迹象

时间:2011-06-23 08:49:38

标签: python numpy

是否有一个很好的简短方法来判断python列表(或numpy数组)是否包含带有交替符号的数字?换句话说:

is_alternating_signs([1, -1, 1, -1, 1]) == True
is_alternating_signs([-1, 1, -1, 1, -1]) == True
is_alternating_signs([1, -1, 1, -1, -1]) == False

7 个答案:

答案 0 :(得分:7)

好的,多亏了SO“相关”功能。我找到this question并通过了ianalis的答案和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]) 

输出

True
True
False

答案 1 :(得分:3)

你可以检查每个偶数成员是否定的,每个奇数成员都是正数,从每一秒开始或从第一个位置开始。同时测试反向以涵盖两种可能性。

这样:

def is_alternating_signs(l):
    return ( (all(x<0 for x in l[::2]) and all(x>=0 for x in l[1::2])) or
             (all(x>=0 for x in l[::2]) and all(x<0 for x in l[1::2])))

答案 2 :(得分:1)

使用decimal模块和is_signed方法:

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() for val in values]
    prevVal = lVals.pop(0)
    for val in lVals:
        if prevVal == val:
            return False
        prevVal = val
    return True

is_alternating_signs(a)
is_alternating_signs(b)
is_alternating_signs(c)

答案 3 :(得分:0)

我喜欢成对:

from itertools import izip, tee

def pairwise(iterable):
    a, b = tee(iterable)
    next(b)
    return izip(a, b)

def is_alternating_signs(iterable):
    return all(x < 0 < y or x > 0 > y for x, y in pairwise(iterable))

如果iterable中没有零,这也​​有效:

def is_alternating_signs(iterable):
    return all((x < 0) == (0 < y) for x, y in pairwise(iterable))

答案 4 :(得分:0)

怎么样...... ...

def is_alternating_signs(aList):
    return all( (aList[i]^aList[i-1])<0 for i in range(1,len(aList)) )

答案 5 :(得分:0)

通过循环一次并测试直接解决方案怎么样?很可能也是最快的,因为许多其他解决方案多次遍历列表。

def signs_are_alternating(numbers):
    """Return True if numbers in given list have alternating signs, False
    otherwise. If given list has less than 2 elements, return False.

    >>> signs_are_alternating([1, -1, 1, -1, 1])
    True
    >>> signs_are_alternating([-1, 1, -1, 1, -1])
    True
    >>> signs_are_alternating([1, -1, 1, -1, -1])
    False

    """
    if len(numbers) < 2:
        return False
    previous_positive = (numbers[0] < 0)  # Pretend it starts alternating
    for number in numbers:
        this_positive = (number >= 0)
        if previous_positive == this_positive:
            return False
        previous_positive = this_positive
    return True

请注意,如果输入列表少于2个元素,我不太清楚预期的行为是什么。

答案 6 :(得分:0)

这是我的单行,可能效率低于其他一些建议:

def is_alternating_signs(lst):
    return all(x * y < 0 for x, y in zip(lst, lst[1:]))