【问题标题】:Determine whether integer is between two other integers确定整数是否在另外两个整数之间
【发布时间】:2023-01-09 14:20:57
【问题描述】:

如何确定给定整数是否介于其他两个整数之间(例如大于/等于10000 和小于/等于30000)?

到目前为止我所尝试的是行不通的:

if number >= 10000 and number >= 30000:
    print ("you have to pay 5% taxes")

【问题讨论】:

  • 检查你的布尔运算符,当然,如果一个数字大于 30000,它就会大于 10000。看看这些小细节,你会发现更多的错误。
  • 请将 >= 30000 更改为 <= 30000
  • 对这个问题所做的最后编辑只是将“解决方案”放入问题代码中。 (使问题有些无效,我认为这违背了这篇文章的目的。)
  • 这个问题显然是指这种比较的语法,与数字 >= 30000 错误无关。编辑很好。

标签: python


【解决方案1】:
if 10000 <= number <= 30000:
    pass

详情见docs

【讨论】:

  • Python 太棒了 :)。并且是多余的:这称为“区间比较”。
  • @MikeC 通过间隔比较,number 首先与10000 进行比较。如果它小于10000,则表达式立即短路并且不检查第二次比较。复杂度是O(1)in range(0, n) 而是生成整个数字序列,然后遍历它。复杂度是O(n)in set(range(0, n))的复杂度仍然是O(n),因为构建集合的时间复杂度是O(n)ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt
  • @MikeC 尝试在你的 shell 中运行:&gt; python -m timeit '10000 &lt;= 10 &lt;= 30000'&gt; python -m timeit '10 in range(10000, 30001)'&gt; python -m timeit '10 in set(range(10000, 30001))'
  • 看起来像在 python3.5.2 中,范围比 if 语句慢 ~10 倍,关于范围检查值的速度恒定......因此很可能是由于函数开销造成的差异。
  • @IanElvister 那是不正确的。 range 不再在 Python 3 中创建列表。请参阅Why is 10**15 in range(10**15+1) so fast in Python 3?
【解决方案2】:
>>> r = range(1, 4)
>>> 1 in r
True
>>> 2 in r
True
>>> 3 in r
True
>>> 4 in r
False
>>> 5 in r
False
>>> 0 in r
False

【讨论】:

  • 哇,我一直认为range(或 python2 中的xrange)返回一个生成器,因此您不能重复测试它。
  • 重要的是要记住4 in range(1,4) 是错误的。所以最好使用1 &gt;= r &lt;= 4,因为它可以避免新手可能犯的错误
  • 1.5 in r 给出 False,即使在 3.4 中也是如此。这个答案只适用于整数。
  • @tripplet,你犯了和OP一样的错误!,应该是1 &lt;= r &lt;= 4
  • (1.) 性能不佳(正如其他人指出的那样看起来挺好的但可能需要很长时间才能执行,因为它是 O(n) 操作与 if a &lt;= x &lt;= b...) (2.) 不适用于 float 类型 (3.) 范围测试不包括在内。 .. 很多开发人员可能会引入错误,因为他们期望包含范围
【解决方案3】:

您的运营商不正确。它应该是if number &gt;= 10000 and number &lt;= 30000:。此外,Python 对这种事情有一个简写,if 10000 &lt;= number &lt;= 30000:

【讨论】:

【解决方案4】:

你的代码 sn-p,

if number >= 10000 and number >= 30000:
    print ("you have to pay 5% taxes")

实际上检查数字是否大于 10000 和 30000。

假设您要检查数字是否在 10000 - 30000 范围内,您可以使用 Python 区间比较:

if 10000 <= number <= 30000:
    print ("you have to pay 5% taxes")

in the Python documentation 进一步描述了此 Python 功能。

【讨论】:

  • 您也可以将它用于初始比较,尽管它毫无用处:if 10000 <= 30000 <= number:
【解决方案5】:

两种方式比较三个整数并检查是否b在。。。之间一种C:

if a < b < c:
    pass

if a < b and b < c:
    pass

第一个看起来更具可读性,但是第二个跑得更快.

让我们比较一下使用dis.dis:

>>> dis.dis('a < b and b < c')
  1           0 LOAD_NAME                0 (a)
              2 LOAD_NAME                1 (b)
              4 COMPARE_OP               0 (<)
              6 JUMP_IF_FALSE_OR_POP    14
              8 LOAD_NAME                1 (b)
             10 LOAD_NAME                2 (c)
             12 COMPARE_OP               0 (<)
        >>   14 RETURN_VALUE
>>> dis.dis('a < b < c')
  1           0 LOAD_NAME                0 (a)
              2 LOAD_NAME                1 (b)
              4 DUP_TOP
              6 ROT_THREE
              8 COMPARE_OP               0 (<)
             10 JUMP_IF_FALSE_OR_POP    18
             12 LOAD_NAME                2 (c)
             14 COMPARE_OP               0 (<)
             16 RETURN_VALUE
        >>   18 ROT_TWO
             20 POP_TOP
             22 RETURN_VALUE
>>>

并使用计时:

~$ python3 -m timeit "1 < 2 and 2 < 3"
10000000 loops, best of 3: 0.0366 usec per loop

~$ python3 -m timeit "1 < 2 < 3"
10000000 loops, best of 3: 0.0396 usec per loop

另外,您可以使用范围,如前所述,但速度要慢得多。

【讨论】:

    【解决方案6】:
    if number >= 10000 and number <= 30000:
        print ("you have to pay 5% taxes")
    

    【讨论】:

      【解决方案7】:

      定义数字之间的范围:

      r = range(1,10)
      

      然后使用它:

      if num in r:
          print("All right!")
      

      【讨论】:

      • range不计算最后一个值10在你的情况下。 range(1,11) 是正确的,如果你需要比较 1 和 10
      【解决方案8】:

      比较的问题是,当你把 &gt;= 放在应该是 &lt;= 的地方时,它们可能很难调试

      #                             v---------- should be <
      if number >= 10000 and number >= 30000:
          print ("you have to pay 5% taxes")
      

      Python 让你只需你的话是什么意思

      if number in xrange(10000, 30001): # ok you have to remember 30000 + 1 here :)
      

      在 Python3 中,您需要使用 range 而不是 xrange

      编辑:人们似乎更关心微基准测试以及链接操作有多酷。我的回答是关于防御性(更少的错误攻击面)编程。

      作为 cmets 声明的结果,我在此处为 Python3.5.2 添加了微基准

      $ python3.5 -m timeit "5 in range(10000, 30000)"
      1000000 loops, best of 3: 0.266 usec per loop
      $ python3.5 -m timeit "10000 <= 5 < 30000"
      10000000 loops, best of 3: 0.0327 usec per loop
      

      如果您担心性能,您可以计算一次范围

      $ python3.5 -m timeit -s "R=range(10000, 30000)" "5 in R"
      10000000 loops, best of 3: 0.0551 usec per loop
      

      【讨论】:

      • 不幸的是,xrange 在 Python 3 中已被弃用。
      • @apraetor,是的,在 Python3 中使用 range(10000, 30001)。它不会创建列表
      • @JBChouinard,你绝对不正确。 Python2 中的xrange 或 Python3 中的range 具有成员资格测试。不信你自己试试。 &lt;= 只是效率更高,因为它不创建范围对象。两种方式都为 O(1)。重点是OP曾是 试图按照你的方式去做,结果出现了一个错误.错误的快速代码更糟。
      • 在 i5 上,(i)python 3.5:%timeit 5 in range(10000, 30000) 1000 个循环,最好的 3:每个循环 451 µs。 %timeit 10000 <= 5 <= 30000 10000000 循环,最好的 3:每个循环 59.4 ns。这是超过 7000 的因数
      • @tback,如果它有可能慢 7000 倍,我不会建议它。也许您可以尝试再次运行测试。
      【解决方案9】:

      虽然 10 &lt;= number &lt;= 20 在 Python 中工作,但我发现使用 range() 的这个符号更具可读性:

      if number in range(10, 21):
          print("number is between 10 (inclusive) and 21 (exclusive)")
      else:
          print("outside of range!")
      

      请记住,第二个上限参数不包含在范围集中,可以通过以下方式验证:

      >>> list(range(10, 21))
      [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
      

      但是,只有当它不在某些性能关键路径上运行时,才更喜欢 range() 方法。对于大多数需求,单次调用仍然足够快,但如果运行 10,000,000 次,我们清楚地注意到与 a &lt;= x &lt; b 相比,性能慢了近 3 倍:

      > { time python3 -c "for i in range(10000000): x = 50 in range(1, 100)"; } 2>&1 | sed -n 's/^.*cpu (.*) total$//p'
      1.848
      
      > { time python3 -c "for i in range(10000000): x = 1 <= 50 < 100"; } 2>&1 | sed -n 's/^.*cpu (.*) total$//p'
      0.630
      

      【讨论】:

      • 请注意,10 &lt;= 10.5 &lt;= 20 为 True,而 10.5 in range(10, 21) 为 False;根据情况,这可能是也可能不是你想要的
      • 虽然这对于浮点数是正确的,但 OP 精确地询问了整数比较。
      • 啊,他们有;在那种情况下,这两个表达式确实是等价的
      【解决方案10】:

      下面是几种可能的方法,从最好到最差的性能排序(即第一个表现最好)

           # Old school check
           if 10000 >= b and b <=30000:
              print ("you have to pay 5% taxes")
           # Python range check
           if 10000 <= number <= 30000:
              print ("you have to pay 5% taxes")
           # As suggested by others but only works for integers and is slow
           if number in range(10000,30001):
              print ("you have to pay 5% taxes")
      

      【讨论】:

      • 我非常喜欢第二种方式!
      【解决方案11】:

      假设有 3 个非负整数:abc。从数学上讲,如果我们想确定c是否在ab之间,包括在内,可以使用这个公式:

      (c - a) * (b - c) >= 0

      或者在 Python 中:

      > print((c - a) * (b - c) >= 0)
      True
      

      【讨论】:

      • 这是执行此操作的最迟钝的方法,同时性能较低
      【解决方案12】:

      当且仅当数字介于 10,000 和 30,000 之间时,您希望输出打印给定的语句。

      代码应该是;

      if number >= 10000 and number <= 30000:
          print("you have to pay 5% taxes")
      

      【讨论】:

      • 已经建议了这个答案。你的答案对问题有何补充?
      【解决方案13】:

      您使用了 >=30000,因此如果数字为 45000,它将进入循环,但我们需要它大于 10000 但小于 30000。将其更改为 <=30000 即可!

      【讨论】:

        【解决方案14】:

        我添加了一个尚未提及的解决方案,使用 sympy 库中的 Interval 类:

        from sympy import Interval
        
        lower_value, higher_value = 10000, 30000
        number = 20000
        
         # to decide whether your interval shhould be open or closed use left_open and right_open 
        interval = Interval(lower_value, higher_value, left_open=False, right_open=False)
        if interval.contains(number):
            print("you have to pay 5% taxes")
        

        【讨论】:

          【解决方案15】:

          试试这个简单的功能;它检查 A 是否在 BC 之间(BC 的顺序可能不正确):

          def isBetween(A, B, C):
              Mi = min(B, C)
              Ma = max(B, C)
              return Mi <= A <= Ma
          

          所以 isBetween(2, 10, -1)isBetween(2, -1, 10) 相同。

          【讨论】:

            【解决方案16】:

            条件应该是,

            if number == 10000 and number <= 30000:
                 print("5% tax payable")
            

            使用 number == 10000 的原因是如果数字的值为 50000 并且如果我们使用 number &gt;= 10000 条件将通过,这不是您想要的。

            【讨论】:

            • 但是,这对于 10001 将失败。他想要 10000 到 30000 之间的数字。您的条件仅适用于数字 == 10000。
            • 这将无法满足用户的要求。这不是一个合适的解决方案。
            猜你喜欢
            • 2012-11-17
            • 1970-01-01
            • 2017-03-31
            • 1970-01-01
            • 2013-06-10
            • 2012-11-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多