【问题标题】:Ordering of evaluation using boolean or使用布尔或求值排序
【发布时间】:2011-04-02 10:57:02
【问题描述】:

所以我得到了这个 sn-p 的代码。它有效(它说 1 是非素数)。:

n = 1
s = 'prime'
for i in range(2, n / 2 + 1):
    if n == 1 or n % i == 0:
        s= 'non-' +s
        break

print s

我的问题是,如果我将第四行更改为:if n % i == 0 or n == 1:,它就不起作用(它说 1 是素数。)

这是为什么呢?既然我使用的是or,应该是其中任何一个都是True,所以订单不计算吗?

(我还在学习布尔值,所以我可能会犯一些基本错误。)

提前致谢!

编辑:感谢您的回答;我从来没有意识到range() 函数的问题。关于代码工作和不工作:我不知道发生了什么。我可能在途中的某个地方犯了一些错误(可能在运行脚本之前忘记保存。虽然我可以发誓它的工作方式不同:P)。也许我只是累了……

无论如何感谢您的回答!

【问题讨论】:

  • 如果你想测试n是否是素数,你只需要检查到n的平方根。
  • 如答案所示,循环不运行。您必须更改某些内容才能让您的代码曾经说过 1 不是素数。另外,在找到n 的因子后不要忘记break

标签: python boolean or-operator


【解决方案1】:

在这两种情况下,循环体都不会运行,因为当'n'为1时,它不在(n,n/2+1)的范围内

您发布的代码说 1 是素数(同样,因为循环体根本不执行)

【讨论】:

    【解决方案2】:

    优先级为fine%首先被评估,然后是==,然后是or,所以它分解成:

         ___or___
        /        \
      ==          ==
     /  \        /  \
    n    1      %    0
               / \
              n   i
    

    您的问题是您的for 循环根本没有被执行,因此s 仍然设置为"prime"

    n 为 1 时的范围 2,n/2+1 等于 2,1,这将导致正文不被执行。

    事实上它不会在n 为2 的地方执行,因为2/2+1 为2 并且范围2,2 不会执行。这些值是开始和终止值,而不是开始和结束(最后一个)值 - 幸运的是,由于 s 的初始化,2 被认为是素数 :-)

    试试这个:

    #!usr/bin/python
    
    n = 9
    s = 'prime'
    if n == 1:
        s = 'non-prime'
    else:
        i = 2
        while i * i <= n:
            if n % i == 0:
                s= 'non-prime'
                break
            i = i + 1
    print s
    

    一直到n/2 很浪费,只需要n 的平方根。

    【讨论】:

    • 我真的没有注意到 :(... 但我不知道发生了什么。我发誓以前的工作方式不同,但我想我只是累了,我在某个地方犯了一些错误方式。感谢您的回答!
    【解决方案3】:

    我认为问题在于当 n 为 1 时,会跳过循环。

    【讨论】:

      【解决方案4】:

      其他答案已经正确解决了您的具体问题(换句话说,循环仅在n/2 + 1 &gt; 2n/2 &gt; 1 时执行,这意味着n &gt; 2 具有新式除法[[python 3或来自未来的合适进口或标志...]],n &gt; 3 带有经典风格的截断除法)。

      写下你提出的具体问题:

      既然我正在使用或者应该是那样 其中任何一个都是 True 所以 订单不算数?

      顺序确实很重要,因为or(如and)是一个短路运算符:具体来说,or 保证从左到右, 如果左操作数为真则停止(因为它不需要知道右操作数)。这对您的特定代码无关紧要,但在以下情况下至关重要,例如:

      if i == 0 or n / i > 3: ...
      

      如果or 没有从左到右(并尽快停止),即使i 等于0,右侧的操作数也可能会被执行——但除法会引发异常!根据 Python 的规则,这段代码 sn-p 不会引发异常(如果 i 至少是一个 int 的话;-)。

      再次重申:这与您遇到的具体问题无关(请参阅其他答案和此问题的开头),但了解未来对您来说很重要,所以,既然您问了,我就接受了有机会解释一下!-)

      【讨论】:

      • @vlad003 排序可以在依赖它的代码中非常重要。例如,a = x or initialize_x()。尽管这是一种糟糕的风格,但您确实可以看到它,并且在您这样做时理解它很重要。如果x 的计算结果为真,则它等价于a = x。否则,它等价于x = initialize_x()。如果您更改顺序,则每次都会调用initialize_x()
      【解决方案5】:
      for n in range(101):
          s = 'prime'
          if n < 2 or not (n & 1): ## not(n & 1) == is even number (last bit 0) == not (n % 2) 
              s = 'non-'+s
          else:
              for i in range(3, int(n**0.5) + 1,2):
                   if not(n % i):
                       s= 'non-' +s
                       break
          print "%i is %s" % (n,s)
      

      您不需要检查所有偶数,您可以在 n 的平方根处停止检查。

      【讨论】:

      • 而不是在内部范围内跨步 2,您可以从 6 开始,跨步 6 检查 i-1 和 i+1。您必须以这种方式手动检查 3。
      • 认为它过于复杂,通常只考虑偶数。否则我会考虑 n % 30 个有效模数的素数。
      猜你喜欢
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多