如何在列表推导式中检查对象是否不为None?

17

我对Python中的列表推导式有一定了解。但是在需要检查列表不为None的情况下,列表推导式会失败。

例如:

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

如果tags为None,则以下列表推导会失败。如果tags为空/ [],则它可以正常工作。我想要一个可以检查None的列表推导。

[k for k,v in tags if tags]:

你正在尝试循环遍历 tags。你可以使用空的集合([], (), {})来实现,但不能使用 None - Ma0
为什么需要列表推导式? - wwii
4
最短方式:[k for k,v in (tags or [])] 的意思是从列表 tags 中获取键(key)的集合,如果 tags 为空列表,则返回一个空集合。 - Matthias
3个回答

31

这样怎么样:

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

让我们看看两种情况会发生什么:

  • >>> tags = None

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

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

    这个方法之所以起作用,是因为(tags or [])只有在bool(tags) == True时才返回tags。否则它会返回第二个参数,在这种情况下为[],即使它的布尔值也是False。这样一来,如果tags存在,我们就遍历它,否则我们就遍历一个空列表。


    太棒了!一个干净的解决方案,避免了使用if语句来检查对象是否为None。 - Korizon

    7
    你可以在这里使用三元条件语句:
    ([k for k, v in tags] if tags is not None else [])
    

    你可以在列表推导式中嵌入三元条件表达式:
    [k for k, v in (tags if tags is not None else [])]
    

    顺便提一句,[k for k, v in tags if tags] 并不像你想象的那样工作。

    列表推导式中的 if 条件在每次迭代时进行评估,这意味着对于其中的每个元素都会检查 tags 的真值。

    举个例子来证明这一点:

    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)
    

    输出:

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

    你需要的是语义上的内联if,也就是在Python中所说的三元条件。

    5
    您可以使用前置if块进行测试。
    if tags is not None:
       ...
    

    或者与一个空可迭代物 短路
    >>> tags = None
    >>> [k for k, _ in tags or ()]
    []
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接