如何在Python中使用`is None`编写单行三元表达式?

时间:2018-01-18 19:20:59

标签: python if-statement

我对使用单行三元表达式而不是传统的多行if-else块感兴趣。但是,比较is None的表达式会产生不同的结果。

以下是比较谓词的条件表达式的两种形式多行一行变体的示例:

  1. if pred is not None
  2. if pred is None
  3. 代码

    import operator as op
    
    
    # First form
    def is_not_none_multiline(a, b, pred=None):
        if pred is not None:
            predicate = pred
        else:
            predicate = lambda x, y: x + y
        return predicate(a, b)
    
    def is_not_none_oneline(a, b, pred=None):
        predicate = pred if pred is not None else lambda x, y: x + y
        return predicate(a, b)
    
    # Second Form
    def is_none_multiline(a, b, pred=None):
        if pred is None:
            predicate = lambda x, y: x + y
        else:
            predicate = pred
        return predicate(a, b)
    
    def is_none_oneline(a, b, pred=None):
        predicate = lambda x, y: x + y if pred is None else pred
        return predicate(a, b)
    

    测试

    以下是mutliline和one-line变体中可选参数的测试。最终的结果出人意料:

    assert is_not_none_multiline(1, 2) == 3
    assert is_not_none_oneline(1, 2) == 3
    assert is_not_none_multiline(1, 2, pred=op.mul) == 2
    assert is_not_none_oneline(1, 2, pred=op.mul) == 2
    
    assert is_none_multiline(1, 2) == 3
    assert is_none_oneline(1, 2) == 3
    assert is_none_multiline(1, 2, pred=op.mul) == 2
    assert is_none_oneline(1, 2, pred=op.mul) == 2
    
    # ----> 4 assert is_none_oneline(1, 2, pred=op.mul) == 2
    # AssertionError: 
    

    虽然pred is not None可以作为一行使用:

    predicate = pred if pred is not None else lambda x, y: x + y
    

    pred is None无法作为一行:

    predicate = lambda x, y: x + y if pred is None else pred
    

    详情

    显然,pred函数作为关键字传递给is_none_oneline()时不会被评估。而是返回:

    print(is_none_oneline(1, 2, pred=op.mul))
    # <built-in function mul>
    

    在执行第二种形式的两种变体时,在Python Tutor可视化中验证了此分析(请参阅此处的可视化is not None multilineis not None one-lineis None multiline,{ {3}})。

    问题

    目前还不清楚为什么等价的三元表达式返回函数而不是计算值。

    1. 有人可以解释为什么不以第二种形式评估谓词 - 一行,pred is None表达式吗?
    2. 如何正确地在一行中写pred is None

1 个答案:

答案 0 :(得分:4)

只是一个简单的运算符优先级的情况。

你得到一个可调用的,它返回一个可调用的。我认为你想要这个,以确保条件以另一种方式分组:

def is_none_oneline(a, b, pred=None):
    predicate = (lambda x, y: x + y) if pred is None else pred
    return predicate(a, b)