1

I am following this:

if else in a list comprehension

but the following small program is generating a syntax error:

def to_rna(dnasequences):
    xlate = {'G': 'C', 'C': 'G', 'T': 'A', 'A': 'U'}
    return ''.join(xlate[sequence] for sequence in dnasequences if sequence in xlate.keys() else raise ValueError)

The else clause is generating the error.

If I remove the else clause it runs, however, I want to raise a ValueError for any input that is NOT a key in my dictionary 'xlate'.

NOTE I am working on the rna-transcription problem from exercism.io.

I pass 5 unit tests but I fail the three unit tests requiring a ValueError for invalid input.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
MarkS
  • 1,455
  • 2
  • 21
  • 36
  • If you can't make the one-liner work, that's a good indication that you're trying to do too much. Just write a normal loop instead. – Jonathon Reinhart Dec 07 '17 at 14:28
  • 1
    If you insist to do it inline, and since you care not about the message anyway, instead of the `raise ValueError` statement just place `int("")` and it will raise a `ValueError` for you. Or, you know, ditch the list comprehension and unwrap your loop to do it properly. – zwer Dec 07 '17 at 14:31

1 Answers1

4

You cannot do this in a comprehension. The conditional expression has the form:

expr if expr else expr

(and, sub-note, it should be used in the beginning of the comprehension)

while raise ExceptionClass is a statement, not an expression. As such, a SyntaxError is raised.

In short, if you do want to use raise, you'll have to resort to a for loop.


Alternately, if you're just very passionate about comprehensions, you could define a function which you can then call in the else clause:

def raiser(exc_type):
    raise exc_type

This is because function calls are expressions. Of course, this is quite ugly.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • 1
    "while raise ExceptionClass is a statement, not an expression." That's what I missed. – MarkS Dec 07 '17 at 14:43
  • Interesting. Is there really no way to do a `raise` statement inside an expression? Even a `lambda` won't help. In extension, @zwer's idea with a message like `int("Hi I am an error")` seems to be the closest thing I can think of. Or the extra method, of course. But yeah, that's rather ugly. – Jeronimo Dec 07 '17 at 15:48
  • @Jeronimo directly, no. The bodies of `lambda`s only [accept expressions too](https://docs.python.org/3/reference/expressions.html#grammar-token-lambda_expr). Indirect approaches such as `int` or a helper function are the only (ugly) options here. – Dimitris Fasarakis Hilliard Dec 07 '17 at 15:55