Извините, если вопрос немного сбивает с толку. Это похоже на этот вопрос

Я думаю, что этот вопрос близок к тому, что я хочу, но в Clojure.

Есть еще один вопрос

Мне нужно что-то вроде этого, но вместо «[br]» в этом вопросе есть список строк, которые нужно искать и удалять.

Надеюсь, я ясно выразился.

Я думаю, что это связано с тем, что строки в Python являются неизменяемыми.

У меня есть список шумовых слов, которые должны быть удалены из списка строк.

Если я использую понимание списка, я снова и снова ищу одну и ту же строку. Таким образом, удаляется только «из», а не «из». Так что мой модифицированный список выглядит так

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)]

Я хотел бы знать, какую ошибку я совершаю.

9
prabhu 18 Авг 2010 в 13:52

4 ответа

Лучший ответ

Вот мой удар в этом. Это использует регулярные выражения.

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 " от "Испания". Для проверки запустите обе версии регулярных выражений против фразы «В Испании дождь».

10
Community 23 Май 2017 в 12:18

Поскольку вы хотели бы знать, что вы делаете неправильно, эта строка:

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

Происходит, а затем начинает зацикливаться на словах. Сначала он проверяет «о». Ваше место (например, "Нью-Йорк") проверяется, чтобы увидеть, начинается ли оно с "из". Он преобразуется (вызывается для замены и удаления) и добавляется в список результатов. Ключевым моментом здесь является то, что результат никогда не проверяется снова. Для каждого слова, которое вы перебираете в понимании, в список результатов добавляется новый результат. Таким образом, следующее слово "the" и ваше место ("Нью-Йорк") не начинается с "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.

1
wds 18 Авг 2010 в 10:13
>>> 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']
4
John La Rooy 18 Авг 2010 в 10:24

Без регулярного выражения вы могли бы сделать так:

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
15
Tony Veijalainen 19 Авг 2010 в 08:34