【问题标题】:Wrote a function to determine if a number is a positive integer and it returns True for negative numbers编写了一个函数来确定一个数字是否为正整数,它对负数返回 True
【发布时间】:2014-03-26 01:16:59
【问题描述】:

我定义了以下函数来测试输入是否为正整数。我计划使用 eval(raw_input("...")) 所以这就是 try-except 部分存在的原因:

def is_ok(x):           # checks if x is a positive integer
    is_int = False
    is_pos = False
    try:
        if type(eval(x)) == int:
            is_int = True
            if x > 0:
                is_pos = True
            else:
                pass
        else:
            pass

    except NameError:
        is_int = False
        print "not even a number!"

    return is_int, is_pos 

如果我尝试传递一个正整数,它将按预期返回 True, True。 它返回 False、False 和非数字的错误消息。

但是,对于负数,它仍然返回 True 以检查它是否为正数。 比如在函数后面加上这个:

is_int, is_pos = is_ok("-9")

print is_int, is_pos

运行打印: 真真

不明白为什么会这样,很想得到你的帮助。 即使有更有效的方法来实现这一点,我仍然想了解它为什么会产生 True True。 谢谢!

(这有点像:Python: How do I assign 2 values I return from a function with 1 input as values outside the function?

【问题讨论】:

标签: python function exception-handling return


【解决方案1】:

为什么不让它变得简单

def is_positive(number):
  if number > 0:
   return True
  else:
    if number <= 0:
     return False

【讨论】:

    【解决方案2】:
    def is_ok(x):
        try:
            return type(x)==int, int(x)>0
        except ValueError:
            return False, False
    

    或者:

    def is_ok(x):
        try:
            return type(x)==int, 'Positive' if int(x)>0 else 'Negative'
        except ValueError:
            return False, 'Neither'
    

    【讨论】:

      【解决方案3】:

      缩短一点:

      def is_ok(x):
          is_int = False
          is_pos = False
          try:
              x = float(x)
              # Check if the number is integer or not
              is_int = x.is_integer()
              if x > 0:
                  is_pos = True
          except ValueError:
              print("not even a number!")
      
          return is_int, is_pos
      

      为了解释它是如何工作的,您可以将一个字符串传递给int() 以将其转换为一个整数。但是,传递无效字符串(如foo)将引发ValueError。我们可以捕捉到它并向用户显示我们的"not even a number!" 消息。比使用eval() 安全得多。

      除非您绝对信任输入,否则请尝试 not to use eval()

      去掉所有变量你也可以做:

      def is_ok(x):
          try:
              # Check if is an integer and greater than 0
              return float(x).is_integer(), float(x) > 0
          except ValueError:
              print("not even a number!")
              return False, False
      

      解释为什么您的代码不起作用

      您最初的问题是它返回True, True 甚至是负数。这里的问题是,当您使用 type(eval(x)) == int 时,您并没有使 x 成为整数对象。当您稍后尝试将字符串与整数进行比较时,这会产生意想不到的效果 (if x &gt; 0):

      In [9]: "twenty" > 0
      Out[9]: True
      

      您可以在very detailed answer 中阅读有关此奇怪行为的更多信息。

      如果您要将 x 重新定义为变量:

      try:
          x = eval(x)
          if type(x) == int:
      

      然后,当您进行比较时,它会表现得更好,并为"-9" 返回True, False

      【讨论】:

      • 您的代码非常优雅。谢谢你。你还能解释一下我在代码中做错了什么,使它对负数打印 True True 吗?再次感谢;)
      • @Optimesh - 我已经更新了我的答案。我希望这会有所帮助。
      • 非常感谢。详细答案也可以参考!
      • Ewan,您的解决方案如何处理浮动?如果 x = 9.8,您在第 5 行将其设置为 9,不是吗?
      • @Optimesh - 确实,它不处理浮点数。如果您希望能够接受浮动,这是一个简单的更改,x = float(x)。我不确定您是否想要这个并选择int(),因为您的示例似乎是整数。更新了我的答案以反映这一点。
      【解决方案4】:

      这一切看起来都不必要地复杂,并且在 raw_input 上使用 eval 存在安全风险 - 用户可以输入他们喜欢的任何内容。

      请尝试以下方法:

      def is_ok(s):
          try:
              i = int(s)
          except ValueError:
              return False, False
          else:
              return True, i >= 0
      

      输入和输出示例:

      >>> for s in ["foo", "9", "-9"]:
          print s, is_ok(s)
      
      
      foo (False, False)
      9 (True, True)
      -9 (True, False)
      

      你的错误在这里:

      if x > 0:
      

      记住x 仍然是一个字符串,在Python 2.x 中所有字符串都会比较&gt; 0

      【讨论】:

      • 谢谢。你能说出为什么我的代码对负数产生 True, True 吗?干杯:)
      【解决方案5】:
      >>> def is_int_positive(n):
      ...     try:
      ...         if n == 0:
      ...             return True, 'Positive'
      ...         elif max(0,int(n)):
      ...             return True, 'Positive'
      ...         else:
      ...             return True, 'Negative'
      ...     except:
      ...         return False, 'Error'
      ...
      >>> for i in [1, 0, -23, 23, 'a']:
      ...     print i, is_int_positive(i)
      ...
      1 (True, 'Positive')
      0 (True, 'Positive')
      -23 (True, 'Negative')
      23 (True, 'Positive')
      a (False, 'Error')
      >>>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-09
        • 2017-07-22
        • 1970-01-01
        • 2015-06-29
        • 2021-08-19
        • 2018-09-15
        • 2020-01-29
        • 1970-01-01
        相关资源
        最近更新 更多