为什么我的过滤器对我的Python列表不起作用?

时间:2019-08-26 20:03:30

标签: python arrays python-3.x filter

我正在使用Python 3.7。我想将正则表达式应用于列表中的每个元素。这是清单

>>> title_words 
['that', 'the', 'famous', 'ukulele', 'medley', '"somewhere', 'over', 'the', 'rainbow/what', 'a', 'wonderful', 'world"', 'by', 'israel', 'kamakawiwoê»ole', 'was', 'originally', 'recorded', 'in', 'a', 'completely', 'unplanned', 'session', 'at', '3:00', 'in', 'the', 'morning,', 'and', 'done', 'in', 'just', 'one', 'take.']

我认为针对列表运行过滤器可以解决问题,但请注意,当我运行

>>> list(filter(lambda s: re.sub(r'^\W+|\W+$', '', s), title_words))
['that', 'the', 'famous', 'ukulele', 'medley', '"somewhere', 'over', 'the', 'rainbow/what', 'a', 'wonderful', 'world"', 'by', 'israel', 'kamakawiwoê»ole', 'was', 'originally', 'recorded', 'in', 'a', 'completely', 'unplanned', 'session', 'at', '3:00', 'in', 'the', 'morning,', 'and', 'done', 'in', 'just', 'one', 'take.']

元素““某处”在开头保留了它的引号。我单独运行了正则表达式,它看起来可以正常工作,但是当我应用过滤器时,东西坏了。哪里出了问题?

2 个答案:

答案 0 :(得分:5)

filter检查过滤器功能的结果是否“真实”以将其包括在结果中。它不会更改元素的值。在这里,您正在调用re.sub,每次都会返回一个非空字符串。

因此您的原始列表未更改。您的意思是简单的列表理解:

filtered = [re.sub(r'^\W+|\W+$', '', s) for s in title_words]

即使在需要过滤的情况下,filter对于lambda来说也没有太大用处,当带有条件的列表/生成器理解可以做同样的事情时,它只会使事情复杂化,而且更加清楚。现在,我意识到您可能希望使用map(也可以使用list()来强制迭代并获得一个硬列表),该方法虽然可行,但仍然过于复杂:

list(map(lambda s: re.sub(r'^\W+|\W+$', '', s), title_words))

(这种方法的唯一兴趣是当您使用multiprocessing.map模块来并行化任务时,但这并不适用)

答案 1 :(得分:1)

当您真正想要的是地图时,您正在使用过滤器。用地图替换过滤器,您应该得到想要的结果。

list(map(lambda s: re.sub(r'^\W+|\W+$', '', s), title_words))

编辑:

正如让恩(Jean)和奥利维尔(Olivier)所提到的那样,如果您只是想将地图转换为列表,则最好使用列表理解。仅当您有很长的title_words列表并且不想将转换应用于整个列表,而是想遍历每一项时(例如,如果您的逻辑可能会停在特定的位置,则使用map才是合适的) title_word,无需查看后面的所有title_words。

fixed_title_words = map(lambda s: re.sub(r'^\W+|\W+$', '', s), title_words)

for title in fixed_title_words:
    if title == 'medley':
        # Perform some action
        break