【问题标题】:How to remove list of words from a list of strings如何从字符串列表中删除单词列表
【发布时间】:2011-03-31 11:08:42
【问题描述】:

对不起,如果问题有点混乱。这类似于this question

我认为上述问题与我想要的很接近,但在 Clojure 中。

another问题

我需要这样的东西,但不是那个问题中的“[br]”,而是需要搜索和删除的字符串列表。

希望我说清楚了。

我认为这是因为python中的字符串是不可变的。

我有一个需要从字符串列表中删除的干扰词列表。

如果我使用列表推导,我最终会一次又一次地搜索相同的字符串。所以,只有“of”被删除,而不是“the”。所以我修改后的列表是这样的

places = ['New York', 'the New York City', 'at Moscow' and many more]

noise_words_list = ['of', 'the', 'in', 'for', 'at']

for place in places:
    stuff = [place.replace(w, "").strip() for w in noise_words_list if place.startswith(w)]

我想知道我犯了什么错误。

【问题讨论】:

  • 你没有说清楚;在此处陈述您的问题,然后如果您认为有必要,请在下方提供具有相似答案的类似问题的链接。

标签: python regex list-comprehension stop-words


【解决方案1】:

没有正则表达式你可以这样做:

places = ['of New York', 'of the New York']

noise_words_set = {'of', 'the', 'at', 'for', 'in'}
stuff = [' '.join(w for w in place.split() if w.lower() not in noise_words_set)
         for place in places
         ]
print stuff

【讨论】:

  • 我遇到了这个,不知道这里发生了什么。如果有人偶然发现这个并想知道发生了什么魔法,它被称为列表理解,这是一篇很好的文章来解释它carlgroner.me/Python/2011/11/09/…
【解决方案2】:

这是我的尝试。这使用正则表达式。

import re
pattern = re.compile("(of|the|in|for|at)\W", re.I)
phrases = ['of New York', 'of the New York']
map(lambda phrase: pattern.sub("", phrase),  phrases) # ['New York', 'New York']

Sans lambda:

[pattern.sub("", phrase) for phrase in phrases]

更新

修复gnibbler 指出的错误(谢谢!):

pattern = re.compile("\\b(of|the|in|for|at)\\W", re.I)
phrases = ['of New York', 'of the New York', 'Spain has rain']
[pattern.sub("", phrase) for phrase in phrases] # ['New York', 'New York', 'Spain has rain']

@prabhu:上述更改避免了从“西班牙”中剪掉尾随的“in”。验证针对短语“Spain has rain”运行正则表达式的两个版本。

【讨论】:

  • 谢谢。它以这种方式工作。当我有机会实现它时,我现在能够更清楚地理解 lambda 的概念。
  • 这不适用于短语“西班牙有雨”。不过很容易修复
  • @Gnibbler:感谢您指出。我正在相应地改变我的答案。
  • 我在模式中添加了“max”这个词,在某些情况下它删除了这个词,在其他情况下它没有。很奇怪,应该有人测试一下,看看他们是否得到了相同的结果。
【解决方案3】:
>>> import re
>>> noise_words_list = ['of', 'the', 'in', 'for', 'at']
>>> phrases = ['of New York', 'of the New York']
>>> noise_re = re.compile('\\b(%s)\\W'%('|'.join(map(re.escape,noise_words_list))),re.I)
>>> [noise_re.sub('',p) for p in phrases]
['New York', 'New York']

【讨论】:

  • 哇!这是一种非常酷的做法,尽管我的大脑很紧张。 :-)
  • 这似乎并没有得到每个单词的实例。例如,“纽约的”变成“纽约的”。
  • @Namey,你可以使用'\\W?\\b(%s)\\W?'之类的东西。如果 OP 没有提供一套全面的测试用例,那就有点麻烦
【解决方案4】:

既然你想知道你做错了什么,这一行:

stuff = [place.replace(w, "").strip() for w in noise_words_list if place.startswith(w)]

发生,然后开始循环单词。首先它检查“of”。检查您的位置(例如“of the New York”)是否以“of”开头。它被转换(调用替换和剥离)并添加到结果列表中。这里的关键是永远不会再次检查结果。对于您在理解中迭代的每个单词,都会将一个新结果添加到结果列表中。所以下一个词是“the”,而你的位置(“of the New York”)不以“the”开头,因此不会添加新结果。

我假设您最终得到的结果是您的位置变量的串联。一个更易于阅读和理解的程序版本是(未经测试):

results = []
for place in places:
    for word in words:
        if place.startswith(word):
            place = place.replace(word, "").strip()
    results.append(place)

请记住,replace() 将删除字符串中任何位置的单词,即使它作为简单的子字符串出现。您可以通过使用带有 ^the\b 之类的模式的正则表达式来避免这种情况。

【讨论】:

  • 谢谢。这很有帮助。
猜你喜欢
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-02
  • 2020-07-21
相关资源
最近更新 更多