谁还没个明天
2008-12-27 08:32
采纳率: 50%
浏览 579

是否有一个条件运算符?

If Python does not have a ternary conditional operator, is it possible to simulate one using other language constructs?

转载于:https://stackoverflow.com/questions/394809/does-python-have-a-ternary-conditional-operator

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

14条回答 默认 最新

  • MAO-EYE 2015-11-23 18:56
    已采纳

    Yes, it was added in version 2.5.
    The syntax is:

    a if condition else b
    

    First condition is evaluated, then either a or b is returned based on the Boolean value of condition
    If condition evaluates to True a is returned, else b is returned.

    For example:

    >>> 'true' if True else 'false'
    'true'
    >>> 'true' if False else 'false'
    'false'
    

    Note that conditionals are an expression, not a statement. This means you can't use assignments or pass or other statements in a conditional:

    >>> pass if False else x = 3
      File "<stdin>", line 1
        pass if False else x = 3
              ^
    SyntaxError: invalid syntax
    

    In such a case, you have to use a normal if statement instead of a conditional.


    Keep in mind that it's frowned upon by some Pythonistas for several reasons:

    • The order of the arguments is different from many other languages (such as C, Ruby, Java, etc.), which may lead to bugs when people unfamiliar with Python's "surprising" behaviour use it (they may reverse the order).
    • Some find it "unwieldy", since it goes contrary to the normal flow of thought (thinking of the condition first and then the effects).
    • Stylistic reasons.

    If you're having trouble remembering the order, then remember that if you read it out loud, you (almost) say what you mean. For example, x = 4 if b > 8 else 9 is read aloud as x will be 4 if b is greater than 8 otherwise 9.

    Official documentation:

    点赞 打赏 评论
  • 胖鸭 2013-01-14 15:56

    You might often find

    cond and on_true or on_false
    

    but this lead to problem when on_true == 0

    >>> x = 0
    >>> print x == 0 and 0 or 1 
    1
    >>> x = 1
    >>> print x == 0 and 0 or 1 
    1
    

    where you would expect for a normal ternary operator this result

    >>> x = 0
    >>> print 0 if x == 0 else 1 
    0
    >>> x = 1
    >>> print 0 if x == 0 else 1 
    1
    
    点赞 打赏 评论
  • bug^君 2013-11-20 10:44

    Simulating the python ternary operator.

    For example

    a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
    result = (lambda:y, lambda:x)[a > b]()
    

    output:

    'b greater than a'
    
    点赞 打赏 评论
  • 10.24 2015-05-05 12:00

    An operator for a conditional expression in Python was added in 2006 as part of Python Enhancement Proposal 308. Its form differ from common ?: operator and it's:

    <expression1> if <condition> else <expression2>
    

    which is equivalent to:

    if <condition>: <expression1> else: <expression2>
    

    Here is an example:

    result = x if a > b else y
    

    Another syntax which can be used (compatible with versions before 2.5):

    result = (lambda:y, lambda:x)[a > b]()
    

    where operands are lazily evaluated.

    Another way is by indexing a tuple (which isn't consistent with the conditional operator of most other languages):

    result = (y, x)[a > b]
    

    or explicitly constructed dictionary:

    result = {True: x, False: y}[a > b]
    

    Another (less reliable), but simpler method is to use and and or operators:

    result = (a > b) and x or y
    

    however this won't work if x would be False.

    A possible workaround is to make x and y lists or tuples as in the following:

    result = ((a > b) and [x] or [y])[0]
    

    or:

    result = ((a > b) and (x,) or (y,))[0]
    

    If you're working with dictionaries, instead of using a ternary conditional, you can take advantage of get(key, default), for example:

    shell = os.environ.get('SHELL', "/bin/sh")
    

    Source: ?: in Python at Wikipedia

    点赞 打赏 评论
  • Didn"t forge 2015-07-15 11:33

    Absolutely, and it is incredibly easy to understand.

    general syntax : first_expression if bool_expression_is_true else second_expression
    
    Example: x= 3 if 3 > 2 else 4 
    # assigns 3 to x if the boolean expression evaluates to true or 4 if it is false
    
    点赞 打赏 评论
  • 10.24 2015-11-17 19:14

    Does Python have a ternary conditional operator?

    Yes. From the grammar file:

    test: or_test ['if' or_test 'else' test] | lambdef
    

    The part of interest is:

    or_test ['if' or_test 'else' test]
    

    So, a ternary conditional operation is of the form:

    expression1 if expression2 else expression3
    

    expression3 will be lazily evaluated (that is, evaluated only if expression2 is false in a boolean context). And because of the recursive definition, you can chain them indefinitely (though it may considered bad style.)

    expression1 if expression2 else expression3 if expression4 else expression5 # and so on
    

    A note on usage:

    Note that every if must be followed with an else. People learning list comprehensions and generator expressions may find this to be a difficult lesson to learn - the following will not work, as Python expects a third expression for an else:

    [expression1 if expression2 for element in iterable]
    #                          ^-- need an else here
    

    which raises a SyntaxError: invalid syntax. So the above is either an incomplete piece of logic (perhaps the user expects a no-op in the false condition) or what may be intended is to use expression2 as a filter - notes that the following is legal Python:

    [expression1 for element in iterable if expression2]
    

    expression2 works as a filter for the list comprehension, and is not a ternary conditional operator.

    Alternative syntax for a more narrow case:

    You may find it somewhat painful to write the following:

    expression1 if expression1 else expression2
    

    expression1 will have to be evaluated twice with the above usage. It can limit redundancy if it is simply a local variable. However, a common and performant Pythonic idiom for this use-case is to use or's shortcutting behavior:

    expression1 or expression2
    

    which is equivalent in semantics. Note that some style-guides may limit this usage on the grounds of clarity - it does pack a lot of meaning into very little syntax.

    点赞 打赏 评论
  • 谁还没个明天 2015-11-23 18:56

    @up:

    Unfortunately, the

    (falseValue, trueValue)[test]
    

    solution doesn't have short-circuit behaviour; thus both falseValue and trueValue are evaluated regardless of the condition. This could be suboptimal or even buggy (i.e. both trueValue and falseValue could be methods and have side-effects).

    One solution to this would be

    (lambda: falseValue, lambda: trueValue)[test]()
    

    (execution delayed until the winner is known ;)), but it introduces inconsistency between callable and non-callable objects. In addition, it doesn't solve the case when using properties.

    And so the story goes - choosing between 3 mentioned solutions is a trade-off between having the short-circuit feature, using at least python 2.5 (IMHO not a problem anymore) and not being prone to "trueValue-evaluates-to-false" errors.

    点赞 打赏 评论
  • 撒拉嘿哟木头 2015-11-23 18:56

    For Python 2.5 and newer there is a specific syntax:

    [on_true] if [cond] else [on_false]
    

    In older Pythons a ternary operator is not implemented but it's possible to simulate it.

    cond and on_true or on_false
    

    Though, there is a potential problem, which if cond evaluates to True and on_true evaluates to False then on_false is returned instead of on_true. If you want this behavior the method is OK, otherwise use this:

    {True: on_true, False: on_false}[cond is True] # is True, not == True
    

    which can be wrapped by:

    def q(cond, on_true, on_false)
        return {True: on_true, False: on_false}[cond is True]
    

    and used this way:

    q(cond, on_true, on_false)
    

    It is compatible with all Python versions.

    点赞 打赏 评论
  • csdnceshi62 2015-11-23 18:56

    From the documentation:

    Conditional expressions (sometimes called a “ternary operator”) have the lowest priority of all Python operations.

    The expression x if C else y first evaluates the condition, C (not x); if C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned.

    See PEP 308 for more details about conditional expressions.

    New since version 2.5.

    点赞 打赏 评论
  • python小菜 2015-11-23 18:56

    You can index into a tuple:

    (falseValue, trueValue)[test]
    

    test needs to return True or False.
    It might be safer to always implement it as:

    (falseValue, trueValue)[test == True]
    

    or you can use the built-in bool() to assure a Boolean value:

    (falseValue, trueValue)[bool(<expression>)]
    
    点赞 打赏 评论
  • ℡Wang Yan 2015-11-23 18:56

    For versions prior to 2.5, there's the trick:

    [expression] and [on_true] or [on_false]
    

    It can give wrong results when on_true has a false boolean value.1
    Although it does have the benefit of evaluating expressions left to right, which is clearer in my opinion.

    1. Is there an equivalent of C’s ”?:” ternary operator?

    点赞 打赏 评论
  • 程序go 2015-11-23 18:56

    expression1 if condition else expression2

    >>> a = 1
    >>> b = 2
    >>> 1 if a > b else -1 
    -1
    >>> 1 if a > b else -1 if a < b else 0
    -1
    
    点赞 打赏 评论
  • 胖鸭 2016-08-21 17:56

    Ternary Operator in different programming Languages

    Here I just try to show some important difference in ternary operator between a couple of programming languages.

    Ternary Operator in Javascript

    var a = true ? 1 : 0;
    # 1
    var b = false ? 1 : 0;
    # 0
    

    Ternary Operator in Ruby

    a = true ? 1 : 0
    # 1
    b = false ? 1 : 0
    # 0
    

    Ternary operator in Scala

    val a = true ? 1 | 0
    # 1
    val b = false ? 1 | 0
    # 0
    

    Ternary operator in R programming

    a <- if (TRUE) 1 else 0
    # 1
    b <- if (FALSE) 1 else 0
    # 0
    

    Ternary operator in Python

    a = 1 if True else 0
    # 1
    b = 1 if False else 0
    # 0
    

    Now you can see the beauty of python language. its highly readable and maintainable.

    点赞 打赏 评论
  • perhaps? 2017-08-20 07:31

    you can do this :-

    [condition] and [expression_1] or [expression_2] ;

    Example:-

    print(number%2 and "odd" or "even")

    This would print "odd" if the number is odd or "even" if the number is even.


    The result :- If condition is true exp_1 is executed else exp_2 is executed.

    Note :- 0 , None , False , emptylist , emptyString evaluates as False. And any data other than 0 evaluates to True.

    Here's how it works:

    if the condition [condition] becomes "True" then , expression_1 will be evaluated but not expression_2 . If we "and" something with 0 (zero) , the result will always to be fasle .So in the below statement ,

    0 and exp
    

    The expression exp won't be evaluated at all since "and" with 0 will always evaluate to zero and there is no need to evaluate the expression . This is how the compiler itself works , in all languages.

    In

    1 or exp
    

    the expression exp won't be evaluated at all since "or" with 1 will always be 1. So it won't bother to evaluate the expression exp since the result will be 1 anyway . (compiler optimization methods).

    But in case of

    True and exp1 or exp2
    

    The second expression exp2 won't be evaluated since True and exp1 would be True when exp1 isn't false .

    Similarly in

    False and exp1 or exp2
    

    The expression exp1 won't be evaluated since False is equivalent to writing 0 and doing "and" with 0 would be 0 itself but after exp1 since "or" is used, it will evaluate the expression exp2 after "or" .


    Note:- This kind of branching using "or" and "and" can only be used when the expression_1 doesn't have a Truth value of False (or 0 or None or emptylist [ ] or emptystring ' '.) since if expression_1 becomes False , then the expression_2 will be evaluated because of the presence "or" between exp_1 and exp_2.

    In case you still want to make it work for all the cases regardless of what exp_1 and exp_2 truth values are, do this :-

    [condition] and ([expression_1] or 1) or [expression_2] ;

    点赞 打赏 评论

相关推荐 更多相似问题