2014-09-04 61 views
2

我想一次測試多個不等式,即多不等式(A <B <C ...)具有潛在的缺失值

if (a < b < c < ...) 

當所有的值都存在其細。然而有時要進行比較的一個或多個變量中的數字值可能會丟失/未知的;在我的情況下,正確的行爲是假設相關的不平等得到滿足。比方說,我給你的特殊價值None當值未知:我從<運營商(或選擇)想要的行爲是:

>>> a = 1; b = 2; c = 3 
>>> a < b < C# this works fine, obviously 
True 
>>> b = None 
>>> a < b < C# would like this to return True 
False 

所以我想True如果一個變量是真正的量比較小其他,或者如果一個變量缺失(需要任何特定的預先確定的非數值),或者如果兩個變量都缺失,並且我希望能夠將比較串起來一起去,即a < b < c < ...
我也想與<=以及<做到這一點。
感謝

+0

我不認爲你可以通過比較可靠地做到這一點 - 你會得到一個值大於在同一時間,任何東西都比任何東西都要小。相反,我會定義一個函數,該函數需要可迭代的值,如果非無值是有序的,則返回True。 – Kos 2014-09-04 12:29:50

+5

如果a是3,b是None,並且c是1,即使a不小於c,a'b Kevin 2014-09-04 12:30:10

+1

如果使用「None」值,Python 3完全拒絕'a 2014-09-04 12:31:04

回答

5

你想測試,如果你的序列 - 酒吧未定義值 - 是按升序排列:

import operator 

def isAscending(strictly, *seq): 
    cmp_op = operator.lt if stricly else operator.le 
    seq = [e for e in seq if e is not None] 
    return all(cmp_op(a, b) for a, b in zip(seq, seq[1:])) 

a, b, c = 1, None, 2 
print isAscending(True, a, b, c) # strictly ascending ? 

編輯的拼寫,以及使用比較操作建議。

+1

您也可以通過比較來用作另一個參數,例如'operator.lt'或者作爲lambda。 – 2014-09-04 13:53:17

+1

拼音nitpick:應該是「嚴格」。 – Kevin 2014-09-04 15:32:46

2

這看起來像你實際上是試圖測試,如果你的價值是獨一無二的,在排序順序可能通過類似替代:

>>> def my_test(l): 
>>>  filt_l = [v for v in l if not v is None] 
>>>  return (sorted(filt_l) == filt_l) and (len(filt_l) == len(set(filt_l))) 

>>> my_test([1,2,3]) 
True 
>>> my_test([1,None,3]) 
True 
>>> my_test([1,4,3]) 
False 
>>> my_test([1,1,3]) 
False 

編輯:包括定時IT似乎sebdelsol建議的功能更快

>>> %timeit isAscending([int(1000*random.random()) for i in xrange(10000)]) 
100 loops, best of 3: 3.44 ms per loop 

>>> %timeit my_test([int(1000*random.random()) for i in xrange(10000)]) 
100 loops, best of 3: 5.67 ms per loop 
+0

如果你寫了'my_test([1,0,3])'會發生什麼? ;)如果v不是v,則將其更改爲「v for v in」。 – flakes 2014-09-04 12:56:20

+1

也考慮將'my_test(l)'更改爲'my_test(* l)'。這樣你不必顯式地在容器中投射參數。即)你可以更接近OP的請求'my_test(a,b,c)' – flakes 2014-09-04 12:59:27

0

我不'認爲你有更好的選擇,而不是定義一個比較函數,只要你想這確實比較,然後寫入的不平等

comp(a,b) and comp(b,c) and ... 
+0

...這不是有效的Python。 – 2014-09-04 12:47:00

+0

@JoelCornett Woops,固定 – HamHamJ 2014-09-04 12:49:38

1

你可以創建自己的類型重載的比較方法(在這個問題:python overloading operators

例如

class N(object): 
    def __init__(self, value): 
     self.value = value 

    def __lt__(self, other): 
     return (self.value is None or self.value < other.value) 
    ... 


a = N(1); b = N(None); c = N(3) 
print a < b < c 
+0

即使在您的示例中也不起作用... ogic僅在第一個值中才起作用。將__th__更改爲:return(self.value是None或self.value Joop 2014-09-04 13:06:04

+0

我也在考慮提出這個問題,但它是不太可用。如果你不必把每個數字都投到這個類上,但是我能想到的所有解決方法比其他一些答案更復雜,也許它會稍微沒有吸引力。所以平衡,+0。 – tripleee 2014-09-04 14:02:45

1

如果你的值在一個列表中([a, b, c]),那麼你可以從它過濾None值,使用zip()將它們配對,將運算符應用於所有對,並查看它們是否全部成立。

在代碼:

import operator # For operator.lt, which is < ("less than") 

def mass_comparify(op, *args): 
    return all(op(a, b) for a, b in zip(args, args[1:]) 
       if a is not None and b is not None) 

print(mass_comparify(operator.lt, 1, None, 3)) # Prints True because 1 < 3 
0

我不知道它是否適合prefectly,但你可以使用reduce

>>> import operator 
>>> reduce(operator.__lt__, [1, None, 3]) 
True 
>>> reduce(operator.__lt__, [1, None, 0]) 
False 

,或者更加堅實,因爲它明確地忽略了無值:

>>> import operator 
>>> reduce(operator.__lt__, filter(None, [1, None, 3])) 
True 
>>> reduce(operator.__lt__, filter(None, [1, None, 0])) 
False 
相關問題