Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have multiple condition clauses in list comprehension?

I'm doing some string parsing and want to return 1 if the character is a letter, 2 if the character is a number, and pass if the character is anything else.

Normally I would just use a for loop and append to it like this

string = 'hello123...'
values = []
for char in string:
    if char.isalpha():
        values.append(1)
    elif char.isdigit():
        values.append(2)

which returns

[1, 1, 1, 1, 1, 2, 2, 2]

as expected. According to https://stackoverflow.com/a/30245465/10029403 using list comprehensions can be much faster. So I tried:

values = [1 if char.isalpha else 2 if char.isdigit for char in string]

However, this is giving me a syntax error as an 'else' is expected.

File "C:/Users/test3.py", line 12
values = [1 if char.isalpha else 2 if char.isdigit for char in string]
                                                     ^
SyntaxError: invalid syntax

I want it to add nothing if the character is anything but alphanumeric. What is wrong with my code?

I will have to execute this function possibly billions of times so if there is a better way to do this, any increase in efficiency is welcome.

like image 779
Cyon Avatar asked Jan 03 '23 02:01

Cyon


1 Answers

If you don't want to consider the particular element at all, you should include that conditional at the end of the comprehension as a guard.

[1 if char.isalpha() else 2 for char in string if char.isdigit() or char.isalpha()]

The if char.isdigit() or char.isalpha() at the end eliminates any elements which fail to satisfy those predicates.

That being said, I recommend factoring at least the translation part (and possibly the conditional as well) to a separate function for the sake of readability. This one-liner, while clever-looking, it not terribly readable.

like image 57
Silvio Mayolo Avatar answered Jan 04 '23 16:01

Silvio Mayolo