【问题标题】:Is there an implication logical operator in python?python中是否有隐含逻辑运算符?
【发布时间】: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


    【解决方案1】:

    p => qnot(p) or q是一样的,你可以试试!

    【讨论】:

    • 这比 (x 和 y) 或不是 x 更简单。谢谢
    • TTL 同意 - 但它不一定那么容易在代码中看到,尽管比原始代码更简单。一个函数——即implies(x, y)——可能有助于更多地传递这个想法,如果这样的构造经常出现足以保证一个名字。
    • @user2246674 同意,为了清晰起见,我建议将其设为一个函数。
    • 创建implies(x, y) 函数的一个潜在问题是:由于Python 的严格评估,结果y 将始终被评估(操作将短-电路)。你会认为这很明显,但我只是花了 30 分钟摸索这个问题。
    【解决方案2】:

    只是因为它很有趣:x => y 在 python 中可能是bool(x) <= bool(y)

    【讨论】:

    • 这是(最终)确凿的证明,True 应该是 -1False 对于布尔值应该是 0! (而不是当前的 Python 约定 True == 1。)因为这样我们就会有 x => y 匹配 y <= x(看起来像从右到左的含义)作为布尔值。
    【解决方案3】:

    有一个逆蕴涵运算符:

    if y ** x:
      do_sth()
    

    这读作:如果 y 被 x 隐含。

    感谢https://github.com/cosmologicon/pywat

    【讨论】:

    • 是的。这正是我一直在寻找的。而且看起来这种相反的含义是无证的,所以@Latty 的回答基本上是不正确的。
    • @running.t 这恰好与x => y 具有相同的效果,但不是用于此目的的运算符。这是幂运算符,不是逻辑运算符,而是数值运算符。它不返回TrueFalse,而是一个数字。这速度较慢,并且可能会引入错误,更不用说令人难以置信的不清楚和难以阅读。我会强烈建议不要这样做,而是按照Juampi's answer 使用not(p) or q
    • 我也希望有一个按位版本。
    • @GarethLatty,运算符的“目的”仅对特定的类/类型有意义(运算符可以而且应该重载)。请注意,+ 运算符可能不是用于执行"Hell" + "o" 的目的。关于未正确重载且未返回 True/False 的布尔值的幂运算符 **,IMO 这是 Python 的错误或错误功能。如果AB 是两个集合,那么A^BA 的幂B)是函数集合B -> A 的标准符号。在 Curry-Howard 对应关系下,函数 B -> A 表示 B => A 的证明。
    • @Alexey “操作员可以而且应该超载。”是一个强有力的声明。运算符很难搜索并依赖于用户对运算符的感知,因此通常应避免使用对大多数人来说含义不是非常清楚的函数。绝大多数阅读该代码的人会发现它没有替代方案那么清晰,而且——无论它是一个错误还是故意没有完成——它都没有有效地实现。你可以争辩说不应该是这样,但目前肯定是这样。鉴于此,我强烈建议不要这样做。
    【解决方案4】:

    你的问题是在 Python 中是否有一个逻辑运算符,简单的答案是否定的:The docs 列出布尔运算,而 Python 根本没有这样的东西。

    显然,正如Juampi's answer 指出的那样,有一些逻辑上等效的操作要短一些,但没有您要求的单个操作符。

    【讨论】:

    • 请看this的回答。似乎并非所有内容都可以在 docs 中找到。
    • @running.t 它不在文档中,因为该答案是错误的 - 没有这样的运算符,相反,这是对另一个运算符的滥用,恰好产生了相同的结果。使用它的最终结果将是非常不清晰、低效的代码,可能会引入错误。
    【解决方案5】:

    根据我在寻找隐含运算符时在这里和那里找到的其他详细信息:您可以使用巧妙的技巧来定义自己的运算符。这是一个运行中的示例,其中注释了导致我得出此结果的来源。

    #!/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)
    

    【讨论】:

      【解决方案6】:

      我认为更可读的单行将是

      x_implies_y = y if x else True
      

      在你原来的例子中:

      if (y if x else True): do_sth()
      

      【讨论】:

        【解决方案7】:

        我发现 XOR 是一个很好的解决方案。您可以将 A 隐含 B 更改为不是 A 或 B。 然后你像这样使用 xor 来否定 A

        A^1 or B
        

        因为 A xor(^) 1 不等于 A

        【讨论】:

          【解决方案8】:

          您可以使用比较运算符<= 来获得两个变量的含义。 示例:

          A   B   A <- B  A <= B
          0   0   1       1
          0   1   1       1
          1   0   0       0
          1   1   1       1
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-15
            • 2011-10-26
            • 1970-01-01
            • 2013-08-14
            • 1970-01-01
            相关资源
            最近更新 更多