列表理解与重复的函数调用

时间:2017-10-31 10:26:09

标签: python list-comprehension

我想转换一个字符串,如下所示:

'   1   ,   2  ,    ,   ,   3   '

进入非空元素列表:

['1', '2', '3']

我的解决方案是这个列表理解:

print [el.strip() for el in mystring.split(",") if el.strip()]

只是想知道,有没有一种很好的,pythonic的方法来编写这种理解而不需要两次调用el.strip()

7 个答案:

答案 0 :(得分:20)

您可以在列表理解中使用生成器:

  [x for x in (el.strip() for el in mylist.split(",")) if x]
#             \__________________ ___________________/
#                                v
#                        internal generator

因此,生成器将提供剥离的元素,并且我们遍历生成器,并且仅检查真实性。因此,我们可以节省el.strip()次电话。

您也可以使用map(..)(使其更具功能性):

  [x for x in map(str.strip, mylist.split(",")) if x]
#             \______________ ________________/
#                            v
#                           map

但这基本上是相同的(尽管生成器的逻辑是 - 在我看来 - 更好的封装)。

答案 1 :(得分:8)

作为获取非空元素列表的简单替代(除了以前的好答案):

import re

s = '   1   ,   2  ,    ,   ,   3   '
print(re.findall(r'[^\s,]+', s))

输出:

['1', '2', '3']

答案 2 :(得分:5)

一些regex如何从字符串中提取所有数字

import re

a = '   1   ,   2  ,    ,   ,   3   '
print(re.findall(r'\d+', a))

输出:

['1', '2', '3']

答案 3 :(得分:3)

只需要一行代码即可获得。当然,如果你想获得幻想,你可以试试功能性方法:

filter(lambda x: x, map(lambda x: x.strip(), mylist.split(',')))

但这会让你简洁换取可见性

答案 4 :(得分:2)

使用以下内容与mapfilter完全一致。

s = '   1   ,   2  ,    ,   ,   3   '
res = filter(None, map(str.strip, s.split(',')))

虽然类似于@ omu_negru的答案,但这可以避免使用lambda,这可能是相当丑陋的,但也会减慢速度。

要过滤的参数None转换为:过滤真相,基本上是x for x in iterable if x,而map只是映射方法str.strip(其默认分割值为空格)到从s.split(',')获得的迭代。

在Python 2上,filter仍然返回一个列表,这种方法应该很容易在速度上忽略其他方法。

在Python 3中,必须使用:

res = [*filter(None, map(str.strip, s.split(',')))]

为了获取列表。

答案 5 :(得分:-1)

如果您已导入" re",则re.split()将起作用:

import re
s='   1   ,   2  ,    ,   ,   3   '
print ([el for el in re.split(r"[, ]+",s) if el])
['1', '2', '3']

如果字符串只用空格分隔(没有插入逗号)不应该分开,那么这将起作用:

import re
s=' ,,,,,     ,,,,  1   ,   2  ,    ,   ,   3,,,,,4   5, 6   '
print ([el for el in re.split(r"\s*,\s*",s.strip()) if el])
['1', '2', '3', '4   5', '6']

答案 6 :(得分:-1)

列表理解很精彩,但使用多行代码并不违法!你甚至可以 - 天堂禁止 - 使用for循环!

result = []
for el in mystring.split(",")
    x = el.strip()
    if x:
        result.append(x)

这是一个两行版本。它实际上与Willem Van Onsem接受的答案相同,但是给出了一个子表达式的名称(并且生成器改为列表,但它对于这个小问题基本没有区别)。在我看来,这使得阅读更容易,尽管代码更多。

all_terms = [el.strip() for el in mystring.split(",")]
non_empty_terms = [x for x in all_terms if x]

其他一些答案当然更短,但我不相信它们中的任何一个更简单/更容易理解。实际上,我认为最好的答案就是你问题中的答案,因为在这种情况下重复是非常小的。