【问题标题】:How to check if object is not None within a list comprehension?如何在列表理解中检查对象是否不是 None ?
【发布时间】:2017-06-28 15:41:46
【问题描述】:

我对 Python 中的列表推导有点熟悉。但是在我需要检查列表是否不是 None 的情况下,列表理解会失败。

例如

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

现在,如果 tags 是 None,那么下面的列表解析会失败。如果标签为空/[],它可以正常工作。我想要一个检查无的列表理解。

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

【问题讨论】:

  • 你试图循环 tags.. 你可以用空的收集器([](){})来做这个,但不能超过None
  • 为什么需要列表理解。
  • 最短路径:[k for k,v in (tags or [])]

标签: python list-comprehension


【解决方案1】:

这个怎么样:

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

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

  • >>> tags = None

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

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

之所以有效是因为(tags or []) 仅在bool(tags) == True 时才返回tags。否则它返回第二个参数,在本例中为[],即使它的布尔值也是False。这样,我们要么循环tags,如果它存在`,或者循环一个空列表,如果它不存在。

【讨论】:

  • 太棒了!一个干净的解决方案,避免使用 if 语句来检查对象是否不是 None。
【解决方案2】:

你可以在这里使用三元条件:

([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中,一个三元条件。

【讨论】:

    【解决方案3】:

    您可以使用前面的 if 块进行测试

    if tags is not None:
       ...
    

    短路 带有一个空的可迭代对象:

    >>> tags = None
    >>> [k for k, _ in tags or ()]
    []
    

    【讨论】:

      猜你喜欢
      • 2016-12-29
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 2018-10-29
      • 2018-07-31
      • 2022-08-22
      • 1970-01-01
      • 2012-12-24
      相关资源
      最近更新 更多