2

我正在研究 Python 中的一个经典学生问题,在一系列条目中找到最大值和最小值。通常,我想通过将所有有效的用户条目放在一个列表中来做到这一点,但我们应该逐个评估每个条目,因为它来自用户。(在这个类中,我们在列表之前覆盖循环。)

由于我没有使用列表,因此我不愿将变量声明为 None,然后评估“最大为 None 或最大 < new”,因为前一种情况只会发生一次。相反,我一直在使用 min() 和 max() ,直到我遇到以下解决方案,这在我看来很优雅,但我的同龄人认为这是可憎的。

那么问题来了:这是对 try/except 的有效使用吗?它比注释的替代方案更不pythonic吗?(当然,最 Pythonic 的方式是 min([list]) 但我在这里。)

#smallest = None

while True:
    num = raw_input("Enter a number: ")
    if num == "done" : break
    try:
        num = int(num)
    except:
        print 'Invalid input'
        continue

    try:
        smallest = min(num,smallest)
    except NameError:
        smallest = num

#    if num < smallest or smallest is None:
#        smallest = num    

print "Minimum is", smallest
4

2 回答 2

2

不,这是对 try/except 的一种非常荒谬的使用。

预先声明并将其定义为None,然后将其更新为

smallest = num if smallest is None else min(num, smallest)

或者,您可以将其初始化为smallest = [],然后将其更新为

smallest = [min(smallest + [num])]

然后完成它

print("Minimum is {}".format(smallest) if smallest else "No numbers!")
于 2014-11-05T01:44:58.677 回答
2

虽然尝试和处理异常通常是 Python 的基本原则——<a href="https://docs.python.org/3/glossary.html#term-eafp" rel="nofollow">EAFP,或者请求宽恕比请求许可更容易——这并不总是合适的。

至少,aNameError是一种通常更多的是代码中需要修复的逻辑错误,而不是需要处理的异常情况,因此这里有一种非常糟糕的“代码气味”。

另外,考虑如果用户从不输入任何数字会发生什么。如果你已经初始化smallest = None了,它会打印出来Minimum is None,这也不算太不合理。如果您未对其进行初始化,它将从 unhandled 打印出堆栈跟踪NameError,这对用户来说不太友好。


但是有一个简单的替代方法:只需选择一个大于任何有效输入的起始值,然后您就不需要检查(无论是通过 EAFP 还是 LBYL):smallest = min(num, smallest)总是正确的答案。

你可以为此使用什么价值?好吧,无穷大显然比任何整数都大,所以你可以从float('inf').

(我不确定是否Minimum is infMinimum is None无值情况更好或更差,但它肯定比回溯更好。)


同时,值得注意的是,有一个更简洁的设计,可以从一开始就避免这个问题。只需分解您的代码以生成整数流,然后您就可以对生成的可迭代对象做任何您想做的事情。例如:

def numbers():
    while True:
        num = raw_input("Enter a number: ")
        if num == "done" : break
        try:
            yield int(num)
        except:
            print 'Invalid input'

smallest = min(numbers())

这具有构建列表的所有优点(您可以调用min它)而没有缺点(您不必实际在内存中构建列表)。

iter您可以通过使用两个参数来进一步简化这一点,raw_input以产生一个字符串生成器,然后分两步将其转换为整数生成器,然后将其传递给min. 但是我认为这样的方式对于新手来说更容易理解。

于 2014-11-05T01:52:17.257 回答