[英]“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
- 我非常故意避免实际的关键词 - 或者像是True
和False
,因为我在谈论每个对象,而不仅仅是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
返回与整个表达式具有相同真值的操作数。
这听起来有点混乱,但只是做它在你的脑袋:如果a
是False
,那么b
不再重要(因为False and anything
将永远是False
),所以它可以返回a
的时候了。
但是当a
为True
只有b
重要,所以它立即返回b
,甚至没有看。
这是许多语言都非常常见且非常基本的优化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.