2010-07-29 2 views
6

में कुशलतापूर्वक एकाधिक स्ट्रिंग प्रतिस्थापन निष्पादित करें यदि मैं एकाधिक स्ट्रिंग प्रतिस्थापन करना चाहता हूं, तो इसे बाहर निकालने का सबसे प्रभावी तरीका क्या है?पाइथन

स्थिति मैं अपने यात्रा में सामना करना पड़ा की तरह का एक उदाहरण इस प्रकार है:

>>> strings = ['a', 'list', 'of', 'strings'] 
>>> [s.replace('a', '')...replace('u', '') for s in strings if len(s) > 2] 
['a', 'lst', 'of', 'strngs'] 
+0

मुझे यकीन नहीं है कि आप लुकअप टेबल का उपयोग कैसे करना चाहते हैं: कुंजी और मूल्य क्या हैं? इसके अलावा, आपके उदाहरण में कुछ टाइपो/असंगतताएं हैं। – zdav

+0

टाइपो कहां हैं? मैंने पठनीयता के लिए उदाहरण को छीनने के लिए एक इलिप्सिस का उपयोग किया है। –

उत्तर

9

विशिष्ट उदाहरण आप (एकल वर्ण हटाने) देने में डुप्लिकेट होने की संभावना है अगर memoize कर सकते हैं translate स्ट्रिंग्स की विधि के लिए बिल्कुल सही है, क्योंकि सिंगल कैरेक्टर वाले एकल वर्णों की प्रतिस्थापन है। यदि इनपुट स्ट्रिंग एक यूनिकोड एक है, तो साथ ही साथ उपरोक्त दो प्रकार के "प्रतिस्थापन", एकाधिक वर्ण तारों वाले एकल वर्णों का प्रतिस्थापन translate विधि के साथ भी ठीक है (यदि आपको बाइट तारों पर काम करने की आवश्यकता नहीं है, हालांकि)।

यदि आपको एकाधिक वर्णों के सबस्ट्रिंग को प्रतिस्थापित करने की आवश्यकता है, तो मैं नियमित अभिव्यक्ति का उपयोग करने की भी सिफारिश करता हूं - हालांकि @ gnibbler के उत्तर की सिफारिश नहीं की जाती है; बल्कि, मैं r'onestring|another|yetanother|orthis' से रेगेक्स का निर्माण करूंगा (उन सबस्ट्रिंग्स में शामिल हों जिन्हें आप लंबवत सलाखों के साथ प्रतिस्थापित करना चाहते हैं - यदि वे विशेष वर्ण हैं, तो निश्चित रूप से re.escape भी सुनिश्चित करें) और एक सरल वस्तु-कार्य को एक निर्देश के आधार पर लिखें।

मैं इस समय बहुत सारे कोड नहीं दे रहा हूं क्योंकि मुझे नहीं पता कि कौन से पैराग्राफ आपकी वास्तविक ज़रूरतों पर लागू होते हैं, लेकिन (जब मैं बाद में घर वापस आ जाता हूं और फिर से एसओ की जांच करता हूं ;-) आपके प्रश्न के आपके संपादन के आधार पर आवश्यकतानुसार एक कोड उदाहरण जोड़ने के लिए मुझे संपादित करने में खुशी होगी (इस उत्तर की टिप्पणियों से अधिक उपयोगी ;-)।

संपादित: एक टिप्पणी में ओ पी कहते हैं कि वे एक "अधिक सामान्य" जवाब (स्पष्ट है कि क्या मतलब है) के बिना अपने क्यू की एक संपादन वह कहते हैं कि वे विभिन्न के टुकड़े के बीच "तालमेल" का अध्ययन करना चाहता में चाहता है तो सभी जिनमें से एकल-वर्ण सबस्ट्रिंग का उपयोग किया जाता है (और मूल रूप से अनुरोध किए जाने के बजाय इसकी उपस्थिति की जांच करें - बिल्कुल अलग-अलग अर्थशास्त्र, निश्चित रूप से)।

इस बोलना और पूर्ण भ्रम सभी मैं कह सकता हूँ यह देखते हुए "समझौतों से जाँच" (प्रदर्शन के लिहाज से) मैं, कोई साइड इफेक्ट समय माप विकृत से बचने के लिए किया है की जाँच करने के उपयोग करने के लिए python -mtimeit -s'setup things here' 'statements to check' (यकीन है कि बयान देने की तरह है के बाद से है कि करने के लिए है timeit सटीक समय माप प्रदान करने के लिए निस्संदेह loops)।

एक सामान्य जवाब (किसी भी तालमेल के बिना, और बहु-चरित्र सबस्ट्रिंग, इसलिए पूरी तरह से अपनी टिप्पणी के लिए अपने क्यू के संपादित के विपरीत लेकिन व्यंजन शामिल - दो पूरी तरह विरोधाभासी किया जा रहा है यह दोनों को पूरा करने के पाठ्यक्रम असंभव की है):

import re 

class Replacer(object): 

    def __init__(self, **replacements): 
    self.replacements = replacements 
    self.locator = re.compile('|'.join(re.escape(s) for s in replacements)) 

    def _doreplace(self, mo): 
    return self.replacements[mo.group()] 

    def replace(self, s): 
    return self.locator.sub(self._doreplace, s) 

उदाहरण उपयोग:

r = Replacer(zap='zop', zip='zup') 
print r.replace('allazapollezipzapzippopzip') 

सबस्ट्रिंग को बदला जाएगा के कुछ अजगर कीवर्ड हैं, वे, एक बालक को पास होने के लिए कम सीधे जैसे की जरूरत है, निम्नलिखित:

r = Replacer(abc='xyz', def='yyt', ghi='zzq') 

ताकि आप उदाहरण के लिए: जरूरत असफल क्योंकि def एक कीवर्ड है होता है, .:

r = Replacer(abc='xyz', ghi='zzq', **{'def': 'yyt'}) 

या की तरह।

मुझे यह कक्षा (प्रक्रियात्मक प्रोग्रामिंग के बजाए) के लिए एक अच्छा उपयोग मिलता है क्योंकि आरई को प्रतिस्थापित करने के लिए सबस्ट्रिंग का पता लगाने के लिए, निर्देश को व्यक्त करने के तरीके को व्यक्त करते हुए, और प्रतिस्थापन करने की विधि, वास्तव में रोना "सभी को एक साथ रखा", और एक वर्ग उदाहरण पाइथन में "एक साथ रखकर" करने का सही तरीका है। एक बंद कारखाने भी काम करेगा (के बाद से replace विधि वास्तव में उदाहरण का ही हिस्सा है कि जरूरतों दिखाई "बाहर" हो रहा है), लेकिन एक, संभवत: कम-स्पष्ट कठिन डिबग करने के लिए रास्ते में:

def make_replacer(**replacements): 
    locator = re.compile('|'.join(re.escape(s) for s in replacements)) 

    def _doreplace(mo): 
    return replacements[mo.group()] 

    def replace(s): 
    return locator.sub(_doreplace, s) 

    return replace 

r = make_replacer(zap='zop', zip='zup') 
print r('allazapollezipzapzippopzip') 

"वास्तविक चर" (replacements, locator, _doreplace) तक पहुंच के रूप में एकमात्र असली लाभ बहुत ही मामूली बेहतर प्रदर्शन हो सकता है (timeit के साथ "बेंचमार्क मामलों" को महत्वपूर्ण और प्रतिनिधि द्वारा उपयोग किए जाने वाले प्रतिनिधि पर जांच की आवश्यकता है) यह मामला सामान्य, वर्ग-आधारित दृष्टिकोण में योग्य नामों (self.replacements आदि) तक पहुंच से तेज़ी से तेज़ हो सकता है (चाहे यह है मामला उपयोग में पाइथन कार्यान्वयन पर निर्भर करेगा, जहां महत्वपूर्ण बेंचमार्क पर timeit के साथ जांच करने की आवश्यकता है!)।

+0

आपके विस्तृत उत्तर एलेक्स के लिए धन्यवाद। मैं वास्तव में एक और सामान्य जवाब की तलाश में था। प्रश्न के अस्पष्ट होने के लिए खेद है। मैं इसे प्रतिबिंबित करने के लिए क्यू संपादित करूंगा। –

0

आप पा सकते हैं कि यह एक regex बना सकते हैं और एक बार में सभी प्रतिस्थापन करने के लिए तेजी से होता है।

भी एक अच्छा विचार है एक समारोह के लिए बाहर प्रतिस्थापन कोड स्थानांतरित करने के लिए इतना है कि आप आप सूची

>>> import re 
>>> [re.sub('[aeiou]','',s) for s in strings if len(s) > 2] 
['a', 'lst', 'of', 'strngs'] 


>>> def replacer(s, memo={}): 
... if s not in memo: 
...  memo[s] = re.sub('[aeiou]','',s) 
... return memo[s] 
... 
>>> [replacer(s) for s in strings if len(s) > 2] 
['a', 'lst', 'of', 'strngs'] 
+0

क्या आप इस पर विस्तार कर सकते हैं? 'Re.sub ('[aeiou]', '', ') एक ही समय में सभी को बदल देंगे? यदि यह चार से चार की जांच कर रहा है, तो मैं पाइथन स्ट्रिंग की अपरिवर्तनीयता के बारे में चिंतित था .. –

+0

@ टिम, हां, '[एईओयू]' सभी स्वरों को एक साथ बदल देता है। अपरिवर्तनीयता कोई समस्या नहीं है क्योंकि आप नए तार बना रहे हैं। –

+0

@ टिम ब्रैक्स '[]' एक वर्ण वर्ग हैं, यह उनमें से किसी एक से मेल खाता है और उस char को प्रतिस्थापन स्ट्रिंग के साथ बदल देता है। यह समाधान अच्छा है अगर: सभी प्रतिस्थापन समान हैं, और यदि आप केवल एकल वर्णों से मेल खाते हैं। – zdav