在python中使用De Morgan定律有什么好处吗?

Pad*_*ham 7 python demorgans-law

我在使用if语句时使用pycharm几次我看到了使用De Morgan法则更改语句的建议,例如使用以下if语句:

if new_odds > 10 and new_odds <= 30:

if not (not (new_odds > 10) or not (new_odds <= 20)):
Run Code Online (Sandbox Code Playgroud)

对我而言,它的可读性较差,使用De Morgan的法律是否有任何优势,还是严格来说是个人选择?

小智 16

德摩根的法律规定:

"不(A和B)"与"(不是A)或(不是B)"相同

并且,

"not(A或B)"与"(不是A)和(不是B)"相同

用于在备用表单之间转换逻辑.因此,虽然您所做的转型符合德摩根的法律,但阅读起来却变得更加困难.正如其他人所建议的那样,简单10 < new_odds <= 30得多可读性更强,要理解这很简单是非常重要的,10 < new_odds and new_odds <= 30因为在此之后你可以做如下逻辑:

10 < new_odds <= 30 != max_odds | default_condition
Run Code Online (Sandbox Code Playgroud)

其中扩展为:

10 < new_odds and new_odds <= 30 and 30 != max_odds and max_odds | default_condition
Run Code Online (Sandbox Code Playgroud)

因此,考虑到语法糖,让我们看另一个例子:

我们将在简单的角色扮演游戏中考虑一个人为的例子,我们将看一个我们称之为"荷兰勇气"的技能.这次攻击的前提是,如果你处于最大生命值,你可以得到奖励,你的护甲或你的攻击等级不足以攻击敌人.我需要知道这条规则什么时候不适用.

写出来我们有4个条件:

A = health == max_health
B = armor > enemy.attack
C = attack > enemy.defense
no_bonus = not(A and not(B and C))
Run Code Online (Sandbox Code Playgroud)

使用De Morgan的定律我可以分解这个:

not(A and not(B and C))
not(A) or not(B and C)
not(A) or not(B) or not(C)
not(health == max_health) or not(armor > enemy.attack) or (attack > enemy.defense)
Run Code Online (Sandbox Code Playgroud)

那么,现在我可以进一步分解......

health < max_meath or armor < enemy.attack < attack > enemy.defense
Run Code Online (Sandbox Code Playgroud)

这里我们假设相反== max_health< max_health,否则它不是最大的.

虽然做作,但这表明我们德摩根定律是一种使我们能够重写逻辑的工具.这种逻辑是否得到改进取决于程序员,但目的是能够生成更简单的结构,这些结构首先更具可读性,其次希望需要更少的指令,因此更快.

  • 这其中存在一些错误;首先也是主要的是,Python 中的运算符链仅适用于比较运算符,即 `30!= max_odds | default_condition` 不会扩展到 `30 != max_odds 和 max_odds | 正如您所指出的,default_condition`。其次,示例中存在错误:分解 `not(A and not(B and C))` 会产生 `not(A) or (B and C)` 而不是 `not(A) or not(B and C) `。后来,最后一个‘不’也神秘消失,最后一个‘或’变成了无关的比较…… (3认同)

mhl*_*ter 7

在Python中,清晰度几乎总是比稍快一点(如果这样甚至可能会更好,我怀疑).

我更喜欢这个更简单的陈述:

if 10 < new_odds <= 30:
Run Code Online (Sandbox Code Playgroud)


aba*_*ert 5

在某些情况下,它使事情更加冗长和可读.但是,如果你已经not散布了一堆s,或者你以不太自然的顺序比较事物,那么demorganing可以减少nots 的数量或逆转不等比较的顺序.例如:

if not foo() and not bar():
if not(foo() or bar()):

if new_score <= high_score and new_level <= high_level:
if not (new_score > high_score or new_level > high_level)
Run Code Online (Sandbox Code Playgroud)

(第二个问题值得商榷......但这正是你对可读性和风格问题的期望.)

因此,如果它使您的代码更具可读性,那就去做吧; 否则,不要.


还有语言(逻辑,约束满意度,关系等),其中这不是真的屈指可数,因为应用not的价值不只是翻转真与假,但产生相反的,可能要慢得多,甚至可能是不确定,查询.

但对于Python或大多数其他"通用"语言来说情况并非如此.