tags:

views:

230

answers:

5

Okay lets say i have a list, and i want to check if that list exists within another list. I can do that doing this:

all(value in some_map for value in required_values)

Which works fine, but lets say i want to the raise an exception when a required value is missing, with the value that it is missing. How can i do that using list comprehension?

I'm more or less curious, all signs seem to point to no.

EDIT Argh I meant this:

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

Looking at those i cant see how i can find the value where the error occured

+2  A: 

If you don't want to consider duplicates and the values are hashable, use sets. They're easier, faster, and can extract "all" elements missing in a single operation:

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))
nosklo
shouldn't it be `missing = required_values - values` ?
ʞɔıu
+2  A: 

You can't use raise in a list comprehension. You can check for yourself by looking at the grammar in the Python Language Reference.

You can however, invoke a function which raises an exception for you.

Laurence Gonsalves
+9  A: 

lets say i want to the raise an exception when a required value is missing, with the value that it is missing. How can i do that using list comprehension?

List comprehensions are a syntactically concise way to create a list based on some existing list—they're not a general-purpose way of writing any for-loop in a single line. In this example, you're not actually creating a list, so it doesn't make any sense to use a list comprehension.

Miles
+1 for "don't abuse list comprehensions"
Soviut
I agree now that i've looked more into it. Thanks.
UberJumper
A: 

While I think using sets (like nosklo's example) is better, you could do something simple like this:

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)
mattkemp
That doesn't put the name of the missing value in the exception, which is the point of the question.
nosklo
Easy enough to fix...
mattkemp
Now it doesn't work. The *all* bultin function fails with any list I try.
nosklo
A: 

Another (ugly) possibility would be the error_on_false function:

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('...')

That's ugly. I'd use the set instead.

nosklo