繁体   English   中英

Python中的“布尔”操作(即:和/或运算符)

[英]“Boolean” operations in Python (ie: the and/or operators)

此方法搜索第一组单词字符(即: [a-zA-Z0-9_] ),返回第一个匹配的组或在发生故障时返回None

def test(str):
    m = re.search(r'(\w+)', str)
    if m:
        return m.group(1)
    return None

相同的功能可以改写为:

def test2(str):
    m = re.search(r'(\w+)', str)
    return m and m.group(1)

这工作原理相同,并且是记录在案的行为; 如此页面明确指出:

表达式x and y首先计算x ; 如果x为false,则返回其值; 否则,将评估y并返回结果值。

但是,作为一个布尔运算符(它甚至在手册上都这样说),我期望and返回一个布尔值。 结果,当我发现(如何)这有效时,我感到惊讶

有什么其他用例,和/或这种相当不直观的实现的理由是什么?

有什么其他用例,

简洁(因此清晰,一旦你习惯它,因为它毕竟不会牺牲可读性! - )任何时候你需要检查一些东西,如果它是真的那么使用那个东西,或者如果那个东西是另一个值是假的(那是为了 - and - 反转它or - 我非常故意避免实际的关键词 - 或者像是TrueFalse ,因为我在谈论每个对象,而不仅仅是bool ! - )。

任何计算机屏幕上的垂直空间都是有限的,并且,根据选择,最好花费在有用的可读性辅助工具(文档字符串,注释,策略性地放置空行来分隔块,......)上,而不是转向,例如:

inverses = [x and 1.0/x for x in values]

分为六个如:

inverses = []
for x in values:
    if x:
        inverses.append(1.0/x)
    else:
        inverses.append(x)

或更狭窄的版本。

和/或这种相当不直观的实施的理由是什么?

由于某些语言(如标准Pascal) 指定评估顺序and和/ or的短路性质,因此初学者不会被“不直观”地绊倒。 Turbo Pascal和语言标准之间的差异之一,在当天使得Turbo成为有史以来最受欢迎的Pascal方言,正是Turbo实现的and并且or像Python稍后做的那样(并且C语言早先做过...... )。

有什么其他用例,

没有。

这种相当不直观的实施的理由是什么?

“直观”? 真? 我不同意。

让我们想想。

如果a是假的,则“a b”被伪造。 所以第一个假值足以知道答案。 为什么要将a转换为另一个布尔值呢? 这已经是假的。 错误多少是False 同样错,对吧?

所以a值 - 当等于False - 足够假,所以这是整个表达式的值。 没有进一步的转换或处理。 完成。

a的值等于True b的值就是所需要的。 没有进一步的转换或处理。 为什么将b转换为另一个布尔值? 这是我们需要知道的全部价值。 如果它像True一样,那就足够了。 真实多少是True吗?

为什么要创建虚假的附加对象?

或的相同分析。

为什么转换为布尔值? 它已经足够或足够假。 真的可以获得多少?


试试这个。

>>> False and 0
False
>>> True and 0
0
>>> (True and 0) == False
True

虽然(True and 0)实际上是0 ,但它等于False 这对于所有实际目的来说都是错误的。

如果这是一个问题,那么bool(a and b)将强制显式转换。

我认为虽然这种符号“有效”,但它代表了一种隐藏逻辑的糟糕编码风格,并且会让更多有经验的程序员感到困惑,他们将掌握大多数其他语言的“知识包袱”。

在大多数语言中,活动函数的返回值由函数类型决定。 除非它被明确重载。 示例'strlen'类型函数应返回整数而不是字符串。

核心关节炎和逻辑函数(+ - / * |&!)等在线功能更加克制,因为它们背后还有正式数学理论的历史。 (想想关于这些函数的操作顺序的所有论据)

要使基本函数返回任何内容,但它们最常见的数据类型(逻辑或数字)应归类为有目的的混淆。

在几乎所有共同语言中,'&'或'&&'或'AND'是逻辑或布尔函数。 在幕后,优化编译器可能在LOGIC FLOW中使用如上所述的短切割逻辑,但不使用数据结构修改(任何以这种方式改变值的优化编译器都会被视为已损坏),但是如果该值预期用于变量为了进一步处理,它应该是逻辑或布尔类型,因为在大多数情况下这是这些运算符的“形式”。

我没有发现这个令人惊讶的事实,并且事实上我希望它在我最初尝试时起作用。

虽然并非所有值都是bools ,但请注意,实际上,所有值都是布尔值 -它们表示真值。 (在Python中, bool实际上是一个表示true或false的值。)数字0不是bool,但它显式(在Python中)的布尔值为False。

换句话说,布尔运算符and并不总是返回一个bool ,但它总是返回一个布尔值; 一个表示真或假的,即使它还有逻辑上附加的其他信息(例如字符串)。

也许这是追溯性的理由; 我不确定,但无论哪种方式,Python的布尔运算符看起来都很自然。


什么时候用?

在您的示例中,test2对我来说更清晰。 我可以告诉他们两者同样如此:test2中的构造并没有让它更难理解。 在其他条件相同的情况下,test2中更简洁的代码 - 稍微 - 更快地理解。 也就是说,这是一个微不足道的差异,我不喜欢足够的,我会跳到重写任何东西。

它在其他方面同样有用:

a = {
    "b": a and a.val,
    "c": b and b.val2,
    "d": c and c.val3,
}

这可以用不同的方式重写,但这是清楚,直接和简洁的。

不要过火; “a()和b()或c()”代替“a()?b():c()”是危险和令人困惑的,因为如果b()是你的话,你最终会得到c()假。 如果您正在编写三元语句,请使用三元语法,即使它非常丑陋: b() if a() else c()

基本上, a and b返回与整个表达式具有相同真值的操作数。

这听起来有点混乱,但只是做它在你的脑袋:如果aFalse ,那么b不再重要(因为False and anything将永远是False ),所以它可以返回a的时候了。

但是当aTrue只有b重要,所以它立即返回b ,甚至没有看。

这是许多语言都非常常见且非常基本的优化。

暂无
暂无

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

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