4

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

all(value in some_map for value in required_values)

哪个工作正常,但是可以说我想在缺少所需值时引发异常,并且缺少它的值。如何使用列表理解来做到这一点?

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

编辑啊,我的意思是:

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

看着那些我看不到如何找到发生错误的值

4

7 回答 7

14

假设我想在缺少所需值时引发异常,并且缺少该值。我如何使用列表理解来做到这一点?

列表推导式是一种基于现有列表创建列表的语法简洁的方法——它们不是for在单行中编写任何-loop的通用方法。在此示例中,您实际上并没有创建列表,因此使用列表推导式没有任何意义。

于 2009-06-02T17:33:13.257 回答
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))
于 2009-06-02T17:24:05.530 回答
2

你不能在列表理解中使用 raise。您可以通过查看Python 语言参考中的语法自行检查。

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

于 2009-06-02T17:27:55.540 回答
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改用。

于 2009-06-02T18:11:28.717 回答
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)]

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

于 2017-09-29T01:31:36.073 回答
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]

But even then it probably makes more sense to handle the exception outside the loop. If you want to raise a custom exception for some reason you can just catch the KeyError and raise your own exception.

try:
    found_values=[some_map[value] for value in required_values]
except KeyError as e:
    raise somecustomException(e.args[0])
于 2019-08-20T13:07:24.780 回答
-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)
于 2009-06-02T17:54:05.937 回答