【发布时间】:2013-04-30 15:07:37
【问题描述】:
我想用python写一个具有逻辑含义的语句。 比如:
if x => y:
do_sth()
当然,我知道我可以使用:
if (x and y) or not x:
do_sth()
但是在 python 中是否有一个逻辑运算符呢?
【问题讨论】:
标签: python math logical-operators implication
我想用python写一个具有逻辑含义的语句。 比如:
if x => y:
do_sth()
当然,我知道我可以使用:
if (x and y) or not x:
do_sth()
但是在 python 中是否有一个逻辑运算符呢?
【问题讨论】:
标签: python math logical-operators implication
p => q和not(p) or q是一样的,你可以试试!
【讨论】:
implies(x, y)——可能有助于更多地传递这个想法,如果这样的构造经常出现足以保证一个名字。
p and not(q)
implies(x, y) 函数的一个潜在问题是:由于Python 的严格评估,结果y 将始终被评估(操作将不短-电路)。你会认为这很明显,但我只是花了 30 分钟摸索这个问题。
只是因为它很有趣:x => y 在 python 中可能是bool(x) <= bool(y)。
【讨论】:
True 应该是 -1 和 False 对于布尔值应该是 0! (而不是当前的 Python 约定 True == 1。)因为这样我们就会有 x => y 匹配 y <= x(看起来像从右到左的含义)作为布尔值。
【讨论】:
x => y 具有相同的效果,但不是用于此目的的运算符。这是幂运算符,不是逻辑运算符,而是数值运算符。它不返回True 或False,而是一个数字。这速度较慢,并且可能会引入错误,更不用说令人难以置信的不清楚和难以阅读。我会强烈建议不要这样做,而是按照Juampi's answer 使用not(p) or q。
+ 运算符可能不是用于执行"Hell" + "o" 的目的。关于未正确重载且未返回 True/False 的布尔值的幂运算符 **,IMO 这是 Python 的错误或错误功能。如果A 和B 是两个集合,那么A^B(A 的幂B)是函数集合B -> A 的标准符号。在 Curry-Howard 对应关系下,函数 B -> A 表示 B => A 的证明。
你的问题是在 Python 中是否有一个逻辑运算符,简单的答案是否定的:The docs 列出布尔运算,而 Python 根本没有这样的东西。
显然,正如Juampi's answer 指出的那样,有一些逻辑上等效的操作要短一些,但没有您要求的单个操作符。
根据我在寻找隐含运算符时在这里和那里找到的其他详细信息:您可以使用巧妙的技巧来定义自己的运算符。这是一个运行中的示例,其中注释了导致我得出此结果的来源。
#!/usr/bin/python
# From http://code.activestate.com/recipes/384122/ (via http://stackoverflow.com/questions/932328/python-defining-my-own-operators)
class Infix:
def __init__(self, function):
self.function = function
def __ror__(self, other):
return Infix(lambda x, self=self, other=other: self.function(other, x))
def __rlshift__(self, other):
return Infix(lambda x, self=self, other=other: self.function(other, x))
def __or__(self, other):
return self.function(other)
def __rshift__(self, other):
return self.function(other)
def __call__(self, value1, value2):
return self.function(value1, value2)
from itertools import product
booleans = [False,True]
# http://stackoverflow.com/questions/16405892/is-there-an-implication-logical-operator-in-python
# http://jacob.jkrall.net/lost-operator/
operators=[
(Infix(lambda p,q: False), "F"),
(Infix(lambda p,q: True), "T"),
(Infix(lambda p,q: p and q), "&"),
(Infix(lambda p,q: p or q) , "V"),
(Infix(lambda p,q: p != q) , "^"),
(Infix(lambda p,q: ((not p) or not q)), "nad"),
(Infix(lambda p,q: ((not p) and not q)), "nor"),
(Infix(lambda p,q: ((not p) or q)), "=>"),
]
for op,sym in operators:
print "\nTruth tables for %s" % sym
print "\np\tq\tp %s q\tq %s p" % (sym,sym)
for p,q in product(booleans,repeat=2):
print "%d\t%d\t%d\t%d" % (p,q,p |op| q,q |op| p)
print "\np\tq\tr\tp %s q\tq %s r\t(p %s q) %s r\tp %s (q %s r)\tp %s q %s r" % (sym,sym,sym,sym,sym,sym,sym,sym)
for p,q,r in product(booleans,repeat=3):
print "%d\t%d\t%d\t%d\t%d\t%d\t\t%d\t\t%d" % (p,q,r,p |op| q,q |op| r, (p |op| q) |op| r, p |op| (q |op| r), p |op| q |op| r)
assert( (p |op| q) |op| r == p |op| q |op| r)
【讨论】:
我认为更可读的单行将是
x_implies_y = y if x else True
在你原来的例子中:
if (y if x else True): do_sth()
【讨论】:
我发现 XOR 是一个很好的解决方案。您可以将 A 隐含 B 更改为不是 A 或 B。 然后你像这样使用 xor 来否定 A
A^1 or B
因为 A xor(^) 1 不等于 A
【讨论】:
您可以使用比较运算符<= 来获得两个变量的含义。
示例:
A B A <- B A <= B
0 0 1 1
0 1 1 1
1 0 0 0
1 1 1 1
【讨论】: