使用列表推导和例外?

时间:2009-06-02 17:22:34

标签: python list list-comprehension

好的,我可以说我有一个列表,我想检查该列表是否存在于另一个列表中。我可以这样做:

all(value in some_map for value in required_values)

哪个工作正常,但是假设我想在缺少必需值时引发异常,并且缺少值。我怎么能用列表理解呢?

我或多或少好奇,所有迹象似乎都指向不。

编辑 Argh我的意思是:

for value in required_values:
 if value not in some_map:
  raise somecustomException(value)

看看那些我无法找到错误发生的值的那些

7 个答案:

答案 0 :(得分:14)

  

假设我想在缺少必需值时引发异常,并且缺少值。我怎么能用列表理解来做到这一点?

列表推导是一种基于某些现有列表创建列表的语法简洁方法 - 它们不是在一行中编写任何for - 循环的通用方法。在这个例子中,你实际上并没有创建一个列表,所以使用列表推导没有任何意义。

答案 1 :(得分:2)

如果您不想考虑重复项并且值是可清除的,请使用集合。它们更容易,更快,并且可以提取单个操作中缺少的“所有”元素:

required_values = set('abc') # store this as a set from the beginning
values = set('ab')
missing = required_values - values
if missing:
    raise SomeException('The values %r are not in %r' % 
                        (missing, required_values))

答案 2 :(得分:2)

你不能在列表理解中使用raise。您可以查看the grammar in the Python Language Reference

来查看自己

但是,您可以调用一个为您引发异常的函数。

答案 3 :(得分:0)

另一个(丑陋的)可能性是error_on_false函数:

def error_on_false(value)
    if value:
        return value
    else:
        raise Exception('Wrong value: %r' % value)

if all(error_on_false(value in some_map) for value in required_values):
    continue_code()
    do_something('...')
那是丑陋的。我会改用set

答案 4 :(得分:0)

我今晚想知道。我的用例是迭代对象列表,并在对象不是特定类型时引发错误。我的解决方案是使用发电机。

def iter_my_class(my_class_list):
    for c in my_class_list:
        if not isinstance(c, MyClass):
            raise ValueError('Expected MyClass')
        yield c

然后用作

classes = [c for c in iter_my_class(my_class_list)]

我在手机上写了这个。如果运行没有错误,你们都欠我一杯啤酒。

答案 5 :(得分:0)

您当然可以将某些东西混在一起,但这不是特别可读。

(_ for _ in ())定义了一个生成器,您可以从中使用throw方法引发所需的任何异常。

all((_ for _ in ()).throw(somecustomException(value)) for value in required_values if value not in some_map)

这就是说,除了可读性之外,除非您实际上打算使用列表,否则使用列表理解是没有意义的。像这样可能更有意义:

map_values=[some_map[value] if value in some_map else (_ for _ in ()).throw(somecustomException(value)) for value in required_values]

但是即使那样,在循环外处理异常可能更有意义。如果由于某种原因要引发自定义异常,则可以捕获KeyError并引发自己的异常。

try:
    found_values=[some_map[value] for value in required_values]
except KeyError as e:
    raise somecustomException(e.args[0])

答案 6 :(得分:-2)

虽然我认为使用集合(比如nosklo的例子)更好,但你可以做一些像这样简单的事情:

def has_required(some_map, value):
  if not value in some_map:
    raise RequiredException('Missing required value: %s' % value)

all(has_required(some_map, value) for value in required_values)