2012-04-24 4 views
0

私は別のストップリストで1つのリストをフィルタリングする素晴らしいpythonic方法を探していますが、最初に2番目のリストから部分文字列を一致させたい。私は、URLのリスト1を持っているし、好きLIST2::。具体的には別のストップワード(部分文字列)の別のリストで、pythonのフィルタリスト

['microsoft.com', 'ibm.com', 'cnn', '.ru'] etc 

URLの最初のリストは、第二のリストは、500〜1000のような、小さい、(項目の何千もの)巨大です。しかし、2番目のリスト項目は部分文字列検索として使用する必要があるため、 "in"またはセットを使用した単純一致は十分ではありません。 私が考えることができるのは2つの "for"ループですが、Pythonでは見えません:)

PS目的は最初のリストから一致する項目を削除することです。

+0

数千人は特に巨大ではありません。数十万人が巨大化している。 – MattH

+0

にはまだ時間がかかります。 たとえば、2000/2000のリストでは、単純な完全な文字列の一致に秒がかかります。 >>> list1 = filter(lambda x:x.lower()はリスト2、リスト1にありません) しかし、部分文字列をチェックする必要があります。 filter()のような効果的な方法を見つける... – alex29

+0

あなたのフィルタリストを拘束することはできますか?あなたの例のうち、「endswith」ではない人は1人だけです。 – MattH

答えて

3

一致する文字列から単一の論理和的な正規表現を作成し、次にREオブジェクトのsearchメソッドを使用して一致させることができます。文字列をre.escapeにしてからREに貼り付けてください。

>>> import re 
>>> substrings = ['microsoft.com', 'ibm.com', 'cnn', '.ru'] 
>>> pattern = "(?:%s)" % "|".join(map(re.escape, substrings)) 
>>> print(pattern) 
(?:microsoft\.com|ibm\.com|cnn|\.ru) 
>>> pattern = re.compile(pattern) 
>>> [x for x in ["www.microsoft.com", "example.com", "foo.ru"] 
... if not pattern.search(x)] 
['example.com'] 
+1

これは驚くほど速いと思われます。私は単純な文字列の検索は、reを使用するよりも速くなると信じていましたが、この解決策は16000と1000のリストに対して2秒しかかかりません。 私は既に2つのリストを一致させるためにこのようなものを作っていましたが、完全一致で2番目のリストを文字列と検索に結合しましたが、部分検索にreを使う考えは素敵です:) – alex29

0

これはあなたの期待ですか?

one=['microsoft.com', 'ibm.com', 'cnn', '.ru'] 
two=['.com'] 
filtered=[o for o in one for t in two if o.find(t)!=-1] 
+0

これはそうではありません - 2番目のリストに含まれていないものを残すだけです。したがって、.find()のすべての結果をチェックし、すべてが否定的な場合は項目を残す必要があります。 – alex29

関連する問題