2011-06-23 36 views
4

是否有一個很好很簡單的方法來判斷一個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

好的,這要歸功於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 
+2

這也是TRUE;爲'[0,1,0,1,0]'。我的建議:'numpy.all(numpy.abs(numpy.diff(numpy.sign(a))== 2)' –

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]))) 
+0

爲什麼'x> = 0'而不是'x> 0'? –

+0

這實際上取決於我們如何定義「交替符號」 - 我可以看到任何一種方式,取決於您是否將零與非負數組合(即將「符號」視爲我們是否通常用負號來書寫)還是將其放入其中自己的無牌類別。 (雖然在這種情況下,你甚至可能會認爲[1,0,1,0]是「交替符號」) – Brian

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) 
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)) 
0

怎麼像...

def is_alternating_signs(aList): 
    return all((aList[i]^aList[i-1])<0 for i in range(1,len(aList))) 
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個元素,我不太確定預期行爲。

0

這裏是我的一行代碼,這比其他的一些建議,可能效率較低:

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