2010-03-08 16 views
59

पर विचार करें ..प्रतिस्थापन के शब्दकोश का उपयोग करके स्ट्रिंग को प्रतिस्थापित करने का सबसे आसान तरीका?

dict = { 
'Спорт':'Досуг', 
'russianA':'englishA' 
} 

s = 'Спорт russianA' 

मैं s में उनके संबंधित dict मूल्यों के साथ सभी dict कुंजी को बदलने के लिए चाहते हैं।

+0

यह इतना सरल नहीं हो सकता है। आपके पास शायद एक स्पष्ट टोकननाइज़र होना चाहिए (उदाहरण के लिए '{' cat ':' russiancat '}' और "कैटरपिलर")। इसके अलावा ओवरलैपिंग शब्द ('{'कार': 'रूसीकार', 'पालतू': 'रूसीपेट'} 'और' कालीन ')। – Joe

+2

यह भी देखें http://code.activestate.com/recipes/81330-single-pass-multiple-replace/ – ChristopheD

+1

एक तरफ के रूप में: मुझे लगता है कि 'dict' को एक चर नाम से बचाया जाता है, क्योंकि इस नाम का एक चर एक ही नाम के अंतर्निर्मित कार्य को छाया करें। – jochen

उत्तर

76

:

>>> d = {'a':'b', 'c':'d'} 
>>> s = "a c x" 
>>> foo = s.split() 
>>> ret = [] 
>>> for item in foo: 
... ret.append(d.get(item,item)) # Try to get from dict, otherwise keep value 
... 
>>> " ".join(ret) 
'b d x' 
+18

यदि कुंजीपटल कुंजियों में "^", "$" और "/" जैसे वर्ण होते हैं, तो नियमित अभिव्यक्ति को इकट्ठा करने से पहले कुंजी को बचने की आवश्यकता होती है। करने के लिए यह, '.join (d.keys())' d.keys()) में कुंजी के लिए '.join (re.escape (key) द्वारा प्रतिस्थापित किया जा सकता है। – jochen

+0

कृपया ध्यान दें कि पहला उदाहरण (Досуг englishA नहीं) केवल python3 में काम करता है। पायथन 2 में यह अभी भी मुझे वापस लौटाता है "Спорт englishA" –

5

एक ही रास्ता है, फिर

d = { 
'Спорт':'Досуг', 
'russianA':'englishA' 
} 

s = 'Спорт russianA'.split() 
for n,i in enumerate(s): 
    if i in d: 
     s[n]=d[i] 
print ' '.join(s) 
+2

यह तब विफल हो जाएगा जब ताना में अपनी चाबियाँ –

3

ghostdog74 के रूप में लगभग एक ही है, हालांकि स्वतंत्र रूप से निर्मित बिना। एक अंतर, डी [] के दायरे में d.get() का उपयोग करके []] वस्तुओं को संभाल नहीं सकता है। फिर से उपयोग करना

reduce(lambda x, y: x.replace(y, dict[y]), dict, s) 
21

आप reduce समारोह इस्तेमाल कर सकते हैं

import re 

s = 'Спорт not russianA' 
d = { 
'Спорт':'Досуг', 
'russianA':'englishA' 
} 

pattern = re.compile(r'\b(' + '|'.join(d.keys()) + r')\b') 
result = pattern.sub(lambda x: d[x.group()], s) 
# Output: 'Досуг not englishA' 

इस पूरे शब्द केवल मेल खाएगी।

pattern = re.compile('|'.join(d.keys())) 

ध्यान दें कि इस मामले में आप शब्द लंबाई से घटते क्रम में क्रमबद्ध चाहिए जब आपके शब्दकोश प्रविष्टियों में से कुछ दूसरों की सबस्ट्रिंग हैं: आपको लगता है कि जरूरत नहीं है, पैटर्न का उपयोग करें।

+13

है, 'कम करें' का उपयोग करके @Max Shawabkeh द्वारा समाधान के लिए अलग-अलग विकल्प एक दूसरे के बाद लागू होते हैं। नतीजतन, शब्दकोशों का उपयोग करके शब्दों को स्वैप करना '{' red ':' green ',' green ':' red '} '' कम'-आधारित दृष्टिकोण के साथ काम नहीं करता है, और ओवरलैपिंग मैचों को अप्रत्याशित तरीके से बदल दिया जाता है। – jochen

+1

बार-बार '.replace() 'कॉलों के बार-बार क्यों न हो, इसका एक अच्छा उदाहरण हो सकता है:' html.replace (' '', '"')। जगह ('&', '&') '- इसे' html पर प्रयास करें = '' foo "'' – zigg

+0

यह क्रिस्टोफेड] (https://stackoverflow.com/a/2401481/216074), या [user2769207] (https : //stackoverflow.com/a/18748467/216074) – poke

16

समाधान found here (मैं अपनी सादगी की तरह):

def multipleReplace(text, wordDict): 
    for key in wordDict: 
     text = text.replace(key, wordDict[key]) 
    return text 
+8

फिर से, जैसा कि @jochen वर्णित है, अगर कोई कुंजी भी है तो यह एक खराब अनुवाद का जोखिम उठाता है। एक एकल पास प्रतिस्थापन सबसे अच्छा होगा। – Chris

1

मैं एक ऐसी ही स्थिति में यह प्रयोग किया जाता है (मेरे स्ट्रिंग सभी अपरकेस में था):

def translate(string, wdict): 
    for key in wdict: 
     string = string.replace(key, wdict[key].lower()) 
    return string.upper() 

आशा व्यक्त की कि किसी तरह से मदद करता है। .. :)

+2

यह क्रिस्टोफ़ेड के समाधान के समान ही है। क्या आप उससे असहमत हैं? – hynekcer

0

चेतावनी के साथ कि कुंजी में स्थान होने पर यह विफल हो जाता है, यह ghostdog74 और extaneons उत्तरों के समान संकुचित समाधान है:

d = { 
'Спорт':'Досуг', 
'russianA':'englishA' 
} 

s = 'Спорт russianA' 

' '.join(d.get(i,i) for i in s.split()) 
संबंधित मुद्दे

 संबंधित मुद्दे