2

我想一次测试多个不等式,即

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 < ...
我也想和 . 一起做<=这个<
谢谢

4

6 回答 6

5

您想测试您的序列(除了未定义的值)是否按升序排列:

import operator

def isAscending(strictly, *seq):
    cmp_op = operator.lt if strictly 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 ?

编辑拼写,并按照建议使用比较运算符。

于 2014-09-04T13:42:43.543 回答
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

编辑:包括时间,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
于 2014-09-04T12:35:45.967 回答
1

您可以创建自己的类型重载比较方法(如这个问题:python 重载运算符

例如

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
于 2014-09-04T12:57:55.593 回答
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
于 2014-09-04T13:57:27.230 回答
0

我认为您没有比定义一个根据需要进行比较的比较函数更好的选择,然后将不等式写为

comp(a,b) and comp(b,c) and ...
于 2014-09-04T12:46:33.627 回答
0

我不知道它是否完美,但你可以使用reduce

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

或者,更可靠,因为它明确忽略 None 值:

>>> import operator
>>> reduce(operator.__lt__, filter(None, [1, None, 3]))
True
>>> reduce(operator.__lt__, filter(None, [1, None, 0]))
False
于 2014-09-04T15:03:41.930 回答