0

当我传递一个空列表时,我试图返回 1 而不是 None reduce(mul, a)。我的代码:

from operator import mul
def product_list(a):
    for b in a:
        b = reduce(mul, a)
        if b == None:
            return 1
        return b

print product_list([])

无论我将 if 语句放在哪里来捕获一个空白列表,我仍然会收到 None 作为输出。我仍在学习基础知识,但这对我来说毫无意义。我什至试过

from operator import mul
def product_list(a):
    if a == None:
        return 1
    else:
        for b in a:
            b = reduce(mul, a)
            if b == None or a == None:
                return 1
            return b

print product_list([])

只是想看看它是否会捕获 None 并返回 1。 reduce() 是否没有按照我认为的方式运行,或者我的代码中是否存在明显的错误,禁止返回 1 并强制返回 None?

4

4 回答 4

6

Whena是一个空列表,您的函数不返回任何内容,默认返回值为None.

测试顶部的空列表:

if not a:
    return 1

在您的第二个函数中,您只测试if a == None,但一个空列表[]永远不会等于None。请注意,测试的惯用方法None是使用is对象身份测试:

if a is None:

相反,通过测试not a,您可以同时捕获a空列表存在的情况None

否则,您的代码毫无意义。您循环a但在第一次迭代中返回并退出该函数:

for b in a:
    b = reduce(mul, a)
    if b == None:
        return 1
    return b  # exit the function here, having only looked at the first element in `a`.

但是,我必须修复您帖子中的缩进,并且可能误解了这些return语句的缩进,在这种情况下,NameError当您传入一个空列表时,您会得到 a 而不是。

于 2013-01-02T19:02:36.433 回答
4

您可以将第三个值传递给reduce,用作起始值。

In [6]: reduce(mul, [], 1)
Out[6]: 1

这是处理空列表的最佳方式。这个案例None真的应该在别处处理,因为它是另一种错误:程序的语义没有错,这是因为其他人给了你错误的数据。你应该明确地抓住它,例如

if not isinstance(..., collections.Iterable):
   # do something

当然,reduce如果你传递一些不可迭代的东西,会引发错误,这对你来说可能就足够了。

于 2013-01-02T19:51:06.897 回答
2

请注意,您并没有像您所说的那样传递一个空列表来减少。尝试一下:

>>> reduce(operator.mul, [])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: reduce() of empty sequence with no initial value

我想也许你不明白这个功能reduce。不过,我们不能反对你——它在 python 代码中的使用并不多。

也许你想定义一个这样的函数:

from operator import mul
def product_list(a):
    try:
        return reduce(mul,a)
    except TypeError:
        return 1

现在你可以试试:

print product_list([1,2,3,4]) #24
print product_list([])  #1
于 2013-01-02T19:07:56.143 回答
0
if a is None or len(a) == 0:
    return 1

如上所述检查空列表条件。

于 2013-01-02T19:03:04.237 回答