2011-02-04 14 views
12

पर खोज और प्रतिस्थापित करने के लिए सबसे तेज़ पायथन विधि मैं एक बहुत बड़ी स्ट्रिंग के अंदर बड़ी संख्या में उप-तारों को प्रतिस्थापित करने का सबसे तेज़ तरीका ढूंढ रहा हूं। यहां दो उदाहरण दिए गए हैं जिनका मैंने उपयोग किया है।एक बड़ी स्ट्रिंग

findall() सरल और अधिक सुरुचिपूर्ण लगता है, लेकिन इसमें एक आश्चर्यजनक समय लगता है।

खोजक() एक बड़ी फ़ाइल के माध्यम से ब्लेज़, लेकिन मुझे यकीन नहीं है कि यह करने का यह सही तरीका है।

यहां कुछ नमूना कोड है। ध्यान दें कि जिस वास्तविक पाठ में मुझे रूचि है, वह लगभग 10 एमबी आकार में एक स्ट्रिंग है, और इन दो तरीकों में एक बड़ा अंतर है।

import re 

def findall_replace(text, reg, rep): 
    for match in reg.findall(text): 
     output = text.replace(match, rep) 
    return output 

def finditer_replace(text, reg, rep): 
    cursor_pos = 0 
    output = '' 
    for match in reg.finditer(text): 
     output += "".join([text[cursor_pos:match.start(1)], rep]) 
     cursor_pos = match.end(1) 
    output += "".join([text[cursor_pos:]]) 
    return output 

reg = re.compile(r'(dog)') 
rep = 'cat' 
text = 'dog cat dog cat dog cat' 

finditer_replace(text, reg, rep) 

findall_replace(text, reg, rep) 

अद्यतन जोड़ा गया re.sub परीक्षण के लिए विधि:

def sub_replace(reg, rep, text): 
    output = re.sub(reg, rep, text) 
    return output 

परिणाम

re.sub() - 0: 00: ००.०३१०००
finditer() - 0 : 00: 00.10 9 000
findall() - 0: 01: 17.260000

+0

और दूसरा एक वास्तव में बहुत तेजी से है? मुझे अजीब लग रहा है, उन्हें लगभग लेना चाहिए। उसी समय। और मुझे लगता है कि दोनों तरीके सही हैं। –

+0

आप पुनः उप विधि का उपयोग क्यों नहीं कर रहे हैं? –

+1

स्ट्रिंग के साथ + = का उपयोग एक ओ (एन^2) ऑपरेशन है, ओ (एन) की सूची बनाने और जुड़ने के लिए "" की तुलना में। –

उत्तर

14

मानक विधि का उपयोग करने के लिए है में निर्मित

re.sub(reg, rep, text) 

संयोग से अपने संस्करणों के बीच प्रदर्शन अंतर के लिए कारण यह है कि अपने पहले संस्करण में प्रत्येक प्रतिस्थापन पूरी स्ट्रिंग recopied जा करने के लिए कारण बनता है। प्रतियां तेजी से होती हैं, लेकिन जब आप 10 एमबी की प्रतिलिपि बनाते हैं, तो पर्याप्त प्रतियां धीमी हो जाएंगी।

+0

धन्यवाद। मैंने re.sub() का उपयोग नहीं किया क्योंकि मैंने सोचा था कि इसे संचालित करने के समान ही था। मैंने फिर से अपने परीक्षण चलाए और re.sub स्पष्ट रूप से सबसे तेज़ तरीका है। परिणाम प्रश्न में जोड़ा गया है। – cyrus

4

आप कर सकते हैं, और मुझे लगता है कि आप करना चाहिए, क्योंकि यह निश्चित रूप से एक अनुकूलित समारोह है, का उपयोग

re.sub(pattern, repl, string[, count, flags]) 

कारण है कि अपने findall_replace() कार्य लंबे समय है कि प्रत्येक मैच में, एक नया स्ट्रिंग वस्तु , बनाई गई है के रूप में आप निम्न कोड निष्पादित द्वारा देखेंगे:,

ch = '''qskfg qmohb561687ipuygvnjoihi2576871987uuiazpoieiohoihnoipoioh 
opuihbavarfgvipauhbi277auhpuitchpanbiuhbvtaoi541987ujptoihbepoihvpoezi 
abtvar473727tta aat tvatbvatzeouithvbop772iezubiuvpzhbepuv454524522ueh''' 

import re 

def findall_replace(text, reg, rep): 
    for match in reg.findall(text): 
     text = text.replace(match, rep) 
     print id(text) 
    return text 

pat = re.compile('\d+') 
rep = 'AAAAAAA' 

print id(ch) 
print 
print findall_replace(ch, pat, rep) 

ध्यान दें कि यह कोड में मैं text = text.replace(match, rep) साथ output = text.replace(match, rep) प्रतिस्थापित अन्यथा केवल पिछले घटना बदल दिया है।

finditer_replace() findall_replace() के लिए एक ही कारण के लिए लंबा है: एक स्ट्रिंग ऑब्जेक्ट का दोहराया निर्माण। लेकिन पूर्व एक पुनरावर्तक re.finditer() का उपयोग करता है जबकि उत्तरार्द्ध एक सूची वस्तु beforhand बनाता है, तो यह लंबा है। यह इटरेटर और नोट-इटरेटर के बीच का अंतर है।

1

वैसे, findall_replace() सुरक्षित नहीं है के साथ अपने कोड, यह unawaited परिणाम वापस कर सकते हैं:

ch = 'sea sun ABC-ABC-DEF bling ranch micABC-DEF fish' 

import re 

def findall_replace(text, reg, rep): 
    for gr in reg.findall(text): 
     text = text.replace(gr, rep) 
     print 'group==',gr 
     print 'text==',text 
    return '\nresult is : '+text 

pat = re.compile('ABC-DE') 
rep = 'DEFINITION' 

print 'ch==',ch 
print 
print findall_replace(ch, pat, rep) 

प्रदर्शन

ch== sea sun ABC-ABC-DEF bling ranch micABC-DEF fish 

group== ABC-DE 
text== sea sun ABC-DEFINITIONF bling ranch micDEFINITIONF fish 
group== ABC-DE 
text== sea sun DEFINITIONFINITIONF bling ranch micDEFINITIONF fish 

result is : sea sun DEFINITIONFINITIONF bling ranch micDEFINITIONF fish 
संबंधित मुद्दे