Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if object is not None within a list comprehension?

I am somehow familiar with list comprehensions in Python. But in situations when I need to check if the list is not None, the list comprehension would fail.

e.g.

tags = v.tags
if tags:
    for t in tags:
        if t['Key'] == 'Name':
            # Do something

Now, if tags is None, then the following list comprehension fails. It works fine if tags is empty/[]. I would like a list comprehension that checks against None.

[k for k,v in tags if tags]:
like image 293
Varun Verma Avatar asked Jun 28 '17 15:06

Varun Verma


2 Answers

How about this:

[k for k in (tags or [])]

Let's see what happens for both cases:

  • >>> tags = None

    >>> [k for k in (tags or [])]
    []
    
  • tags = [1, 2, 3]

    >>> [k for k in (tags or [])]
    [1, 2, 3]
    

The reason this works is because (tags or []) returns tags only if bool(tags) == True. Otherwise it returns the second argument, in this case [], even if its boolean value is also False. That way, we either loop over tags, if it exists` or over an empty list if it doesn't.

like image 199
Ma0 Avatar answered Sep 28 '22 02:09

Ma0


You can use a ternary condition here:

([k for k, v in tags] if tags is not None else [])

You can embed the ternary condition in the comprehension as well:

[k for k, v in (tags if tags is not None else [])]

As a side note, [k for k, v in tags if tags] does not really behave as you might expect. The if clause of a list comprehension is evaluated at each iteration, meaning that the truth value of tags is checked for each element in it.

To prove this:

l = [1, 2, 3, 4, 5]

def is_empty(l):
    print("is_empty")
    return len(l) > 0

m = [i for i in l if is_empty(l)]

print(m)

Output:

is_empty
is_empty
is_empty
is_empty
is_empty
[1, 2, 3, 4, 5]

What you are semantically looking for is an inline if, that is, in Python, a ternary condition.

like image 29
Right leg Avatar answered Sep 28 '22 02:09

Right leg