【问题标题】:How to think like a Computer Scientist exercise如何像计算机科学家一样思考练习
【发布时间】:2013-05-22 22:50:17
【问题描述】:

因此,正如标题所暗示的那样,这是该书中的一个示例。 我对编程仍然很陌生,并且难以调试。话虽如此,欢迎任何批评,特别是如果它显示了一种更有效的编码方式;请记住,我还是新手,所以如果你向我扔一个新的内置函数或其他东西,我很可能不知道你指的是什么。

所以这个练习的重点是编写一个函数,给它三个参数,以确定这三个参数是否形成一个三角形。这是我的代码:

def is_triangle(a,b,c):
    num_list = [a,b,c]
    biggest = max(num_list)
    other_two = num_list.remove(biggest)
    sum_of_two = sum(other_two)

    if sum_of_two > biggest:
        print 'Congrats, %d, %d, and %d form a triangle!' % (a,b,c)
    elif sum_of_two == biggest:
        print 'That forms a degenerate triangle!'
    else:
        print 'That does\'t make any sort triangle... >:['


def sides():
    side1 = raw_input('Please input side numero Juan: ')
    side2 = raw_input('Now side two: ')
    side3 = raw_input('...aaaannnd three: ')
    import time
    time.sleep(1)
    print 'Thanks >:]'
    side1 = int(side1)
    side2 = int(side2)
    side3 = int(side3)
    is_triangle(side1,side2,side3)

sides()

然而,每当我运行它时,我都会得到以下信息:

Traceback (most recent call last):
  File "A:/Python/is_triangle.py", line 27, in <module>
    sides()
  File "A:/Python/is_triangle.py", line 25, in sides
    is_triangle(side1,side2,side3)
  File "A:/Python/is_triangle.py", line 5, in is_triangle
    sum_of_two = sum(other_two)
TypeError: 'NoneType' object is not iterable

我的猜测是 sum_of_two 行,但我不知道它有什么问题。有人可以帮我调试一下吗?

我花了一个小时在没有内置函数的情况下重写它(以各种方式,到处都是ors)。但它看起来很糟糕,我宁愿学着这样写。

【问题讨论】:

  • list.remove() 删除了第一次出现的值,因此数字为(5, 5, 2) 的情况应该不成问题。
  • 顺便说一句,+1 为我们提供了完整的代码和错误。
  • @steveha,gnibbler:你知道什么,谢谢。我不经常使用该功能。 :)
  • @GregHewgill:这有什么区别(两侧相等)(根据代码)?
  • @0xc0de:我最初的评论(现已删除)是基于对 .remove() 所做的事情的误解。

标签: python python-2.7 nonetype


【解决方案1】:

问题在于remove 修改了基础列表 - 它不返回新列表。将其更改为:

num_list.remove(biggest)
sum_of_two = sum(num_list)

要了解发生这种情况的确切原因,请在 IDLE 中尝试以下操作:

>>> x = [1,2,3,4,5]
>>> x.remove(1)
>>> x
[2,3,4,5]

【讨论】:

  • 是的!谢谢!今天已经学到了一些新东西。我认为当我在这里粘贴我的代码时缩进搞砸了,但感谢其他所有人的输入。
【解决方案2】:

既然num_list.remove(biggest) 返回None,请考虑这个

other1, other2, biggest = sorted(num_list)
sum_of_two = other1 + other2

看起来if 块也需要缩进

def is_triangle(a, b, c):
    num_list = [a, b, c]
    other1, other2, biggest = sorted(num_list)
    sum_of_two = other1 + other2

    if sum_of_two > biggest:
        print 'Congrats, %d, %d, and %d form a triangle!' % (a,b,c)
    elif sum_of_two == biggest:
        print 'That forms a degenerate triangle!'
    else:
        print 'That does\'t make any sort triangle... >:['

【讨论】:

  • 很好,忘了我也能做到这一点。谢谢
【解决方案3】:

你只是犯了一个非常常见的错误,一个简单的错误。在 Python 中,当函数导致数据结构发生更改时,它不会返回更改后的结构。通常它返回None。如果函数获得新的数据结构或新值,则返回它。

所以,str.lower() 实际上并没有改变字符串;它返回一个新字符串,其中字符为小写。如果您有一些名为lst 的列表并且您运行sorted(lst),它不会更改列表;它返回一个已排序的新列表。但是lst.sort() 对列表进行就地排序,因此它不会返回对列表的引用;它返回None

在下面的 cmets 中,@lvc 指出 list.pop() 从列表中删除一个值并返回该值。因此,这是一个更改数据结构并返回 None 以外的其他内容的函数示例,但它仍然绝对不返回对更改后的数据结构的引用。

list.remove() 函数改变一个列表,它返回None。您需要做的就是更改您的函数以对所有内容使用相同的列表:首先使用列表查找最大值,然后从列表中删除最大值,然后将列表传递给sum()

Python 这样做的原因是为了遵守“命令/查询分离”原则。

http://en.wikipedia.org/wiki/Command%E2%80%93query_separation

【讨论】:

  • +1 用于解释 为什么 remove 返回 None,尽管在 每个 情况下都不是这样 - 这里特别相关的是list.pop 带有一个参数,其行为几乎与 OP 所期望的 list.remove 完全相同(返回删除的内容,而不是剩下的内容)。
  • @lvc, list.pop() 遵循“命令/查询分离”规则,因为它不返回被修改的东西(列表)。它返回从列表中提取的值。原始代码假设list.remove() 会返回修改后的列表;它不会,list.pop() 也不会。
  • @lvc,我认为您提出了一个正确的更大观点:我的解释过于简单化了。我说过,改变数据结构的 Python 函数总是返回 None,显然不像你的 list.pop() 示例所示的那样。我将编辑答案以澄清一点。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
相关资源
最近更新 更多