Python字符串中使用 "and" 和 "or" 运算符

30

我不理解这行Python代码的含义:

parameter and (" " + parameter) or ""

此处使用字符串与逻辑运算符andor,而变量parameter的类型是字符串。

在这种情况下,我想问一个问题:既然我无法想象在字符串上使用布尔运算符会有意义的情况,那么:

为什么有人想要在Python字符串中使用逻辑andor运算符,特别是在上述表达式的情况下有什么意义?

stackoverflow上关于非布尔值下如何使用“and”和“or”? 的答案以及目前给出的答案解释了上面代码行的作用,但仍未回答这个问题:“为什么有人想要在Python字符串中使用逻辑andor运算符,特别是在上述表达式的情况下有什么意义(相比于编写其他可能实现相同效果的代码选项)?”

上述问题涉及应用于字符串的逻辑andor运算符,这一问题尚未被stackoverflow上其他问题所涵盖,因此不是重复问题。


7
这段代码是 " " + parameter if parameter else "",增加了一些混淆。 - zch
1
@Smac89:这是有道理的,但有些人会认为这不符合Python的风格。 - Tim Pietzcker
6个回答

34

假设您正在使用参数的值,但如果该值为None,则通常希望使用空字符串""而不是None。一般情况下您会怎么做?

if parameter:
    # use parameter (well your expression using `" " + parameter` in this case
else:
    # use ""

这是表达式的含义。首先你需要了解andor运算符的作用:

  • a and b如果a为True,则返回b,否则返回a
  • a or b如果a为True,则返回a,否则返回b

因此,你的表达式:

parameter and (" " + parameter) or ""

实际上等同于:

(parameter and (" " + parameter)) or  ""
#    A1               A2               B
#           A                     or   B

如果:

  • parameter - A1 评估为 True:

    result = (True and " " + parameter) or ""
    
    result = (" " + parameter) or ""
    
    result = " " + parameter
    
  • 参数 - A1None:

    result = (None and " " + parameter) or ""
    
    result = None or ""
    
    result = ""
    

一般建议使用A if C else B形式的条件表达式,这样更好且更易读。因此,你最好使用:

" " + parameter if parameter else ""

查看PEP 308 - 条件表达式以了解使用条件表达式代替给定表达式的原因。


然而,请注意,如果参数是一个具有字符串值但同时具有一些副作用的表达式,那么在第一种情况下,'parameter and ""'和'parameter if parameter else ""'可能会导致不同的行为,因为在第一种情况下,参数只会被评估一次,而在第二种情况下(if...else语法),参数将被评估两次。 - Jay

8

Python将空字符串视为布尔值"false",非空字符串视为布尔值"true"。

因此,表达式只有两种可能的结果,即对于空字符串和非空字符串。

第二个需要注意的是"or"和"and"运算符返回的值。Python不仅返回true或false值,对于字符串和or/and运算符,它返回其中一个字符串(考虑到它们具有true或false的值)。Python使用懒惰方法:

对于"and"运算符,如果左值为true,则检查并返回右值。如果左值为false,则返回左值

对于"or"运算符,如果第一个值为true,则返回第一个值。否则,如果第二个值为false,则返回第二个值

parameter = 'test'
print( parameter and (" " + parameter) or "" )

输出: 测试

parameter = ''
print( parameter and (" " + parameter) or "" )

输出:(空字符串)


5
在Python中,空字符串等同于False布尔值,就像空列表一样。你所提供的代码行是三元运算符的Python版本(如下面的注释所指出的那样,现在已经过时,因为Python 现在有一个真正的三元运算符)。它基于三个规则:
  • a and b:如果aFalse,那么b将不会被评估
  • a or b:如果aTrue,那么b将不会被评估
  • 逻辑语句的值是其最近评估表达式的值
如果 parameter 评估为 True,则将评估 and 子句的第二部分:(" " + parameter)。因此,如果parameter不是空字符串,则会在其前面添加空格。由于整个表达式是TrueTrue或"anything"始终是True),因此不会评估or子句的第二部分。
如果 parameterFalse(在此上下文中为空字符串),则不会评估and子句的第二部分,并且您已经可以确定它是FalseFalse和任何内容始终是False)。因此,将评估or子句的第二部分,返回一个空字符串。
您可以以更详细的方式编写它:
if parameter:
    return " " + parameter
else:
    return ""

2
考虑这个TTL。然后只需插入不同的场景,看看会发生什么 :)
请注意andor 评估为使它们“成功”或“失败”的第一个值 - 这不一定是True或False!
a    b    a or b   a and b
--   --   ------   ------- 
T    T    a (T)    b (T)
T    F    a (T)    b (F)
F    T    b (T)    a (F)
F    F    b (F)    a (F)

T和F代表“真值”和“假值”。这种表达式链接之所以“可行”,是因为运算符不需要返回True或False——它将是ab的值。

2

它检查parameter是否有值。如果有,它会在其前面添加一个空格。如果没有,则返回一个空字符串。

$ python
Python 2.7.2 (default, Oct 11 2012, 20:14:37) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> foo = 'bar'
>>> foo and (" " + foo) or ""
' bar'

正确,但您可能需要解释一下它是如何工作的。 - Tim Pietzcker

1

在所有好的答案中,我发现以下陈述有助于我更好地记住并符合我的大脑工作方式(希望对其他人也有帮助):

  • “and”返回第一个False项(例如None,“”,[],(),{},0)或者如果没有,则返回最后一项(例如找不到False)

  • “or”返回第一个True项或最后一项(例如找不到True)

总之,它们都返回决定语句结果的第一项。(在最坏的情况下,是序列中的最后一项)

请注意,此规则也适用于链接的所有“and”或所有“or”语句。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接