2012-06-14 22 views

Odpowiedz

8

Najbardziej imporant poprawa jest do make stopWords a set. Oznacza to, że wyszukiwań będzie bardzo szybko

stopWords = set(["the", "and", "with", etc...]) 
" ".join(word for word in msg.split() if word not in stopWords) 

Jeśli chcesz tylko wiedzieć, czy którykolwiek z stopwords są w tekście

if any(word in stopWords for word in msg.split()): 
    ... 
+0

Czy to jest bardziej wydajne niż tworzenie wyrażeń regularnych? – mlt

+0

@mlt, możliwe że nie. Praca tak odmienna od tej, że trudno ją zgadnąć. Powinieneś napisać odpowiedź za pomocą wyrażeń regularnych –

1

Korzystanie list comprehension:

stopWords = ["the", "and", "with"] 
msg = "kill the fox and the dog" 

' '.join([w for w in msg.split() if w not in stopWords]) 

daje:

'kill fox dog' 
+1

'w nie w stopWords' dostanie wolniej jak stopwords staje się dłuższy, ponieważ musi iterację listę, aby sprawdzić każdy. Dlatego właśnie tworzenie stopworda jest ważne –

+0

@gnibbler Ok, tak zauważono, dzięki. Zawsze chętnie uczę się czegoś nowego (nie używam zestawów prawie na tyle często). – Levon

0
  1. umieścić swoją pierwotną listę słów w słowniku.
  2. Powtórz znaki w danym ciągu, używając spacji jako separatora dla słowa. Wyszukaj każde słowo w słowniku.
3

W Pythonie najszybsza operacja spowoduje, że "stopwords" stanie się zbiorem zamiast listy i sprawdzi bezpośrednio dla członkostwa z "x w stopwords". Ta struktura została zaprojektowana tak, aby była szybka dla tego rodzaju operacji.

See the set documentation

0

miec stopwords w set() (jak inni sugerują), gromadzić inne swoje słowa do sprawnego ustawić po prostu wziąć różnicę ustawić za pomocą working = working - stopWords ... mieć pracę set wszystkie z stopWords odfiltrowane z niego. Lub po prostu sprawdzić istnienie takich słów, użyj warunkowego. Na przykład:

#!python 
stopWords = set('the a an and'.split()) 
working = set('this is a test of the one working set dude'.split()) 
if working == working - stopWords: 
    print "The working set contains no stop words" 
else: 
    print "Actually, it does" 

Istnieje rzeczywiście bardziej efektywnych struktur danych, takich jak trie które mogłyby zostać wykorzystane dla dużych, stosunkowo gęsta, zestaw stopu słów. Możesz znaleźć moduły Trie dla Pythona, ale nie widziałem żadnych napisanych jako binarnych (C) rozszerzeń i zastanawiam się, gdzie byłby punkt przejścia między wersją zaimplementowaną w czystym Pythonie a użyciem Pythona w obsłudze set(). (Może to być również dobry przypadek dla Cython).

W rzeczywistości widzę, że ktoś zmierzył się z tym pytaniem osobno tutaj SO: How do I create a fixed length mutable array of python objects in cython.

Oczywiście powinieneś stworzyć prostą wersję opartą na zestawie, przetestować ją i profilować, a następnie, jeśli to konieczne, wypróbować warianty trie i Cython-trie jako możliwe ulepszenia.

0

Alternatywnie można złożyć listę w wyrażeniu regularnym i zastąpić słowa zatrzymania wraz z otaczającymi je przestrzeniami pojedynczym odstępem.

import re 
stopWords = ["the", "and", "with"] 
input = "Kill the fox and dog" 
pattern = "\\s{:s}\\s".format("\\s|\\s".join(stopWords)) 
print(pattern) 
print(re.sub(pattern, " ", input)) 

wyjście wola

\sthe\s|\sand\s|\swith\s 
Kill fox dog