चूंकि आप mystring
के विरुद्ध शब्द-दर-शब्द संसाधित कर रहे हैं, निश्चित रूप से mystring को सेट के रूप में उपयोग किया जा सकता है। तो बस mystring
में शब्द और शब्दों के समूहों को लक्षित युक्त सेट के बीच चौराहे ले:
In [370]: mystring=set(['foobar','barfoo','foo'])
In [371]: mystring.intersection(set(['foo', 'bar', 'hello']))
Out[371]: set(['foo'])
आपका तार्किक 'या' दो सेट के चौराहे के सदस्यों है।
एक सेट का उपयोग करना भी तेज़ है। यहाँ एक जनरेटर और नियमित अभिव्यक्ति बनाम रिश्तेदार समय कर रहे हैं:
f1: generator to test against large string
f2: re to test against large string
f3: set intersection of two sets of words
rate/sec f2 f1 f3
f2 101,333 -- -95.0% -95.5%
f1 2,026,329 1899.7% -- -10.1%
f3 2,253,539 2123.9% 11.2% --
तो एक जनरेटर और in
आपरेशन के लिए रेगुलर एक्सप्रेशन से 19x तेजी से होता है और एक सेट चौराहे 21x एक regex की तुलना में तेजी और 11% एक जनरेटर की तुलना में तेजी है।
यहाँ कोड है कि समय उत्पन्न होता है:
import re
with open('/usr/share/dict/words','r') as fin:
set_words={word.strip() for word in fin}
s_words=' '.join(set_words)
target=set(['bar','foo','hello'])
target_re = re.compile("(%s)" % ("|".join(re.escape(word) for word in target),))
gen_target=(word for word in ('bar','foo','hello'))
def f1():
""" generator to test against large string """
if any(s in s_words for s in gen_target):
return True
def f2():
""" re to test against large string """
if re.search(target_re, s_words):
return True
def f3():
""" set intersection of two sets of words """
if target.intersection(set_words):
return True
funcs=[f1,f2,f3]
legend(funcs)
cmpthese(funcs)
स्रोत
2012-06-25 13:49:43
धन्यवाद। लेकिन क्या तकनीक शॉर्ट सर्किट अनुकूलन को रोकती है? – ereOn
यह एक जनरेटर है, सूची नहीं। – johv
नहीं। '(' foo ',' bar ',' हैलो 'में एस के लिए mystring में है' 'एक जनरेटर अभिव्यक्ति है, जिसका अर्थ है कि यह पूरी तरह से पूरी तरह से गणना के रूप में तुरंत गणना नहीं की जाती है। 'कोई भी()' पहले वास्तविक मूल्य को देखने पर पुनरावृत्ति को रोकता है, इसलिए बाकी की जांच कभी नहीं की जाएगी। जनरेटर अभिव्यक्तियों पर पढ़ें। – Kos