在python中使用德摩根定律有什么好处吗?



我使用pycharm和几次使用if语句时,我看到了使用de Morgan Laws更改语句的建议,例如使用以下if语句:

if new_odds > 10 and new_odds <= 30:
if not (not (new_odds > 10) or not (new_odds <= 20)):

对我来说,这使得它不可阅读,因此使用de Morgan的定律有任何优势,还是严格的个人选择?

de Morgan的定律说明:

"不是(a和b)与"(不是a)或(不是b)"

相同

以及

"不是(A或B)与"(不是a)和(不是b)"

相同

用于在替代形式之间转换逻辑的

。因此,尽管您做到的转型符合De Morgan的法律,但它变得更加困难。正如其他人建议的更简单的 10 < new_odds <= 30将更加可读性,但是非常重要的是要了解10 < new_odds and new_odds <= 30这是简短的,因为从中,您可以做逻辑,例如:

10 < new_odds <= 30 != max_odds | default_condition

扩展到:

10 < new_odds and new_odds <= 30 and 30 != max_odds and max_odds | default_condition

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

我们将在简单的角色扮演游戏中考虑一个人为的示例,在该游戏中,我们会查看一种我们将"荷兰语勇气"的技能。这次攻击的前提是,如果您处于最大健康状态,则可以奖金,而您的装甲或攻击等级不足以攻击敌人。我需要知道何时不适用此规则。

写这本书我们有4个条件:

A = health == max_health
B = armor > enemy.attack
C = attack > enemy.defense
no_bonus = not(A and not(B and C))

使用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)

好吧,现在我可以进一步分解...

health < max_meath or armor < enemy.attack < attack > enemy.defense

在这里,我们假设== max_health< max_health,否则不是最大值。

尽管人为人为,但这表明 de Morgan的定律是使我们能够重写逻辑的工具。该逻辑是否得到改进取决于程序员,但目的是能够产生更简单的构造,首先是更可读的,其次,其次是希望更少的说明,因此更快。

在python中,几乎是总是更清楚地比稍微快(如果那样,我怀疑)。

我更喜欢这个甚至更简单语句:

if 10 < new_odds <= 30:

在某些情况下,它使事情变得更加详细和可读。但是,如果您已经散布了一堆not S,或者以不太自然的顺序比较事物的情况下,Demorganing可以减少not S的数量或反向不平等比较的顺序。例如:

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)

(第二个是有争议的……但这正是您从可读性和风格问题中所期望的。)

因此,如果它使您的代码更可读,请执行;否则,不要。


少数语言(逻辑,约束 - 满意度,关系等),因为这是不正确的,因为将not应用于值不仅是真实的和false产生相反的问题,可能会慢得多,甚至可能不确定,查询。

但是,python或大多数其他"通用"语言并非如此。

给定下面的结果,似乎更复杂/更易读的表达式也是最慢的。无论如何,可读性在大多数情况下都在Python中更有价值。

In [1]: new_odds = 0  
In [2]: %timeit if new_odds > 10 and new_odds <= 30: pass  
10000000 loops, best of 3: 24.3 ns per loop
In [3]: %timeit if not (not (new_odds > 10) or not (new_odds <= 20)): pass  
10000000 loops, best of 3: 48.6 ns per loop  
In [4]: %timeit if 10 < new_odds <= 30:pass  
10000000 loops, best of 3: 43.4 ns per loop  
In [5]: new_odds = 20  
In [6]: %timeit if new_odds > 10 and new_odds <= 30: pass  
10000000 loops, best of 3: 57.7 ns per loop  
In [7]: %timeit if not (not (new_odds > 10) or not (new_odds <= 20)): pass  
10000000 loops, best of 3: 102 ns per loop  
In [8]: %timeit if 10 < new_odds <= 30:pass  
10000000 loops, best of 3: 52.7 ns per loop

有时对可读性可能很有用,但执行时是同一件事。例如:

not(A AND B) === not(A) OR not(B)
if not a() and not b():
if not(a() or b()):

a() true或false的执行将相同。

以您的示例,最好的解决方案仍然是使用Python语法的力量并写下:

if 10 < new_odds <= 30:

此语法对于检查数字值在特定范围内非常有用。

相关内容

  • 没有找到相关文章

最新更新