I have a mapping as a dict
{
'a': ['a1','a2','a3'],
'b': ['b1', 'b2'],
'c': ['c1', 'c2', 'c3', 'c4]
}
Given a sentence, all occurrences of 'a1', 'a2', 'a3' should be replaced with 'a', similarly all occurrences of 'b1', 'b2' should be replaced with 'b'. How can this be done efficiently? This is the current code:
def word_replacer(text):
s = {
'a': ['a1','a2','a3'],
'b': ['b1', 'b2'],
'c': ['c1', 'c2', 'c3', 'c4']
}
words = text.split(" ")
for idx, word in enumerate(words):
changed_word=[k for k, v in s.items() if word in [vals.lower() for vals in v]]
if ((len(changed_word)>0) and (word != changed_word[0])):
words[idx] = changed_word[0]
result = " ".join(words)
return result
CodePudding user response:
It would be easier to just reverse the dict and make a quick single look-up. If you can, just change it manually. If it's an input:
mapping = {v: k for k, l in s.items() for v in l}
And now the code is much simpler:
def word_replacer(text):
s = {
'a': ['a1','a2','a3'],
'b': ['b1', 'b2'],
'c': ['c1', 'c2', 'c3', 'c4']
}
mapping = {v: k for k, l in s.items() for v in l}
words = text.split()
for idx, word in enumerate(words):
words[idx] = mapping[word]
result = " ".join(words)
return result
Or even simpler using the get
method of dicts:
def word_replacer(text):
s = {
'a': ['a1','a2','a3'],
'b': ['b1', 'b2'],
'c': ['c1', 'c2', 'c3', 'c4']
}
mapping = {v: k for k, l in s.items() for v in l}
return " ".join(mapping.get(word, word) for word in text.split())
CodePudding user response:
An efficient approach would be to create a dict that maps aliases to the mapped words, so that you can use the dict.get
method to look up each word in constant time and replace it with the mapped value if found:
s = {
'a': ['a1', 'a2', 'a3'],
'b': ['b1', 'b2'],
'c': ['c1', 'c2', 'c3', 'c4']
}
mapping = {alias: word for word, aliases in s.items() for alias in aliases}
def word_replacer(text):
return ' '.join(mapping.get(word, word) for word in text.split())
so that:
print(word_replacer('a1 b2 c3 d4'))
outputs:
a b c d4