【问题标题】:using list comprehension in a IF statement [duplicate]在 IF 语句中使用列表推导[重复]
【发布时间】:2013-01-18 17:29:47
【问题描述】:

可能重复:
Return the first item in a list matching a condition

如何使用列表推导轻松获取“匹配”列表元素?例如我有一个list,我正在寻找一个以某个字符串开头的元素。这很容易做到:

>>> lines = ['AHP Buildlife number', 'NIT-Version-Default-v0.16.0', 'E_release v2.3.14.0']
>>> [ x.strip() for x in lines if x.startswith('NIT-Version-Default') ]
['NIT-Version-Default-v0.16.0']

但是我怎样才能在if 语句中做同样的事情,以便匹配的列表元素可以用于进一步处理;像这样的东西:

>>> if [ x.strip() for x in lines if x.startswith('NSS-Checkin-Default') ]:
...   ver = x.split('-')[-1].strip()
...   print ver

因此,它返回 v0.16.0 作为版本号。这显然是行不通的,但希望你明白我想要做什么。知道怎么做吗?干杯!!

PS。欢迎您改进问题或标题。

【问题讨论】:

  • 请注意,如果您以后不想使用该值,只需检查是否存在,最好的解决方案是any()

标签: python list-comprehension


【解决方案1】:

如果您只寻找一个元素:

x = next(x.strip() for x in lines if x.startswith('NSS-Checkin-Default'))
ver = x.split('-')[-1].strip()

请注意,我使用了生成器表达式(a for b in c if d),而不是列表理解[a for b in c if d]。这样,lines 上的迭代只会在实际需要的时间内完成(在这种情况下,直到找到第一个元素)。

如果没有找到元素,next 将引发 StopIteration


如果你还想确保恰好有一个元素(或者对于某个固定的 N 来说正好有 N 个元素),你可以这样写(分配给一个元组):

(x,) = (x.strip() for x in lines if x.startswith('NSS-Checkin-Default')

在这种情况下,如果生成器表达式产生的元素太少或太多,您将拥有ValueError。这称为“元组解包”。

另见:

What is the best way to get the first item from an iterable matching a condition?

【讨论】:

    【解决方案2】:

    简单:您的列表推导返回一个包含一个元素的列表,因此您只需访问该元素:thelist[0]

    从您的示例中获取:

    lines = ['AHP Buildlife number', 'NIT-Version-Default-v0.16.0', 'E_release v2.3.14.0']
    results = [ x.strip() for x in lines if x.startswith('NIT-Version-Default') ]
    ver = results[0].split('-')[-1].strip()
    print ver
    

    【讨论】:

    • 我猜如果他只对第一项感兴趣,那么就不需要创建整个列表。
    【解决方案3】:

    请参阅map 函数。相反,我不认为理解是至关重要的:

    map(lambda x: x.split('-')[-1].strip(),
            filter(lambda x: x.startswith('NIT'), lines)) 
    

    【讨论】:

    • map(lambda x: f(x), seq) 只是写[f(x) for x in seq]的更长的方式。
    • @Kos,当然可以,除非地图需要 lambda(您的示例)。
    • 我遵循的一个约定是“当你已经拥有函数时使用 map/filter,否则使用理解”。除非您使用的是 map 的 var-arg 变体。
    【解决方案4】:
    >>> for each in lines:
    ...     match=re.search("(^NIT-Version-Default).*(v[0-9.]+)",each)
    ...     if match:
    ...             print match.group(2)
    ... 
    v0.16.0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-06
      • 2014-10-19
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 1970-01-01
      • 2019-11-03
      • 2013-05-06
      相关资源
      最近更新 更多