简体   繁体   English

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

[英]How to write one-line ternary expressions using `is None` in Python?

I am interested in using one-line ternary expressions instead of traditional multiline if-else blocks. 我对使用单行三元表达式而不是传统的多行if-else块感兴趣。 However, expressions comparing is None give different results. 但是,“ is None比较的表达式给出不同的结果。

Here is an example comparing multiline and one-line variants of two forms of a conditional expression for a predicate: 这是一个比较谓词的两种形式的条件表达式的多行单行变体的示例:

  1. if pred is not None
  2. if pred is None

Code

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)

Tests 测试

Here are tests for optional arguments in mutliline and one-line variants. 这是对多行和单行变体中的可选参数的测试。 The final result was unexpected: 最终结果出乎意料:

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: 

Although pred is not None works as one-line: 尽管pred is not None可以作为单行:

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

pred is None does not work as one-line: pred is None不能用作单行:

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

Details 细节

Apparantly, the pred function is not evaluated when passed in as a keyword to is_none_oneline() . 显然,当作为关键字传递给is_none_oneline()时,不会评估pred函数。 Rather, it is returned: 而是返回:

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

This analysis was verified in a Python Tutor visualization when executing both variants of the second form (see visualizations here is not None multiline , is not None one-line , is None multiline , is None one-line ). 在执行第二种形式的两种变体时,此分析已在Python Tutor可视化中得到验证(请参见此处的可视化is not None multilineis not None one-lineis None multilineis None -line )。

Questions 问题

It is unclear why an equivalent ternary expression returns a function rather than a computed value. 不清楚为什么等效的三元表达式返回函数而不是计算值。

  1. Can someone explain why the predicate is not evaluated in the second form - a one-line, pred is None expression? 有人可以解释为什么谓词不以第二种形式求值吗?单行,谓词pred is None表达式?
  2. How does one correctly write pred is None in one-line? 如何在一行中正确编写pred is None

Just a simple case of operator precedence. 只是操作符优先级的简单情况。

You're getting a callable which returns a callable. 您得到一个可调用对象,该可调用对象返回可调用对象。 I think you wanted this instead, to make sure the conditional gets grouped the other way: 我认为您想要这样做,以确保以另一种方式对条件进行分组:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM