Looks like a good opportunity to use a loop:
mapping = { 'A':'1', 'B':'2', 'C':'3', 'D':'4', 'E':'5'}
for k, v in mapping.iteritems():
my_string = my_string.replace(k, v)
A faster approach if you don't mind the parentheses would be:
mapping = [ ('A', '1'), ('B', '2'), ('C', '3'), ('D', '4'), ('E', '5') ]
for k, v in mapping:
my_string = my_string.replace(k, v)
Answer from Rick Copeland on Stack OverflowA list of string replacements in Python - Stack Overflow
Making str.replace() accept lists - Ideas - Discussions on Python.org
python - Substitute patterns with values from lists - Code Review Stack Exchange
Trying to replace characters in a list of strings?
Looks like a good opportunity to use a loop:
mapping = { 'A':'1', 'B':'2', 'C':'3', 'D':'4', 'E':'5'}
for k, v in mapping.iteritems():
my_string = my_string.replace(k, v)
A faster approach if you don't mind the parentheses would be:
mapping = [ ('A', '1'), ('B', '2'), ('C', '3'), ('D', '4'), ('E', '5') ]
for k, v in mapping:
my_string = my_string.replace(k, v)
You can easily use string.maketrans() to create the mapping string to pass to str.translate():
import string
trans = string.maketrans("ABCDE","12345")
my_string = my_string.translate(trans)
I would prefer to take Iterable[tuple[str, Iterable[str]]] rather than dict[str, list[str]] for two reasons:
Iterableallows for a wider range of inputs than binding to concrete types.Adding
.items()in the function call is largly an irrelevant change.print(replace_in_string(TextFileContent, replacements.items()))
terms = copy.deepcopy(replacements)
IIRC deep copy will copy all of the values in the dictionary, even the strings. We can reduce the memory usage by only 'copying' the dictionary and setting the values to iterators (iter) and then advancing the iterator in replace_func.
terms = {k: iter(vs) for k, vs in replacements.items()}
def replace_func(m):
return next(terms[m.group()])
Tests
It's nice to see that you have included various tests to verify that replace_in_string works as expected.
Docstring
Its great that you have provided a docstring, but I think it could be a bit more descriptive (argument string is not even mentioned). For example:
"""
string: a str.
replacements: a dictionary whose keys are strings and whose values
are lists of string replacements.
For each key in replacements, search string for occurrences
of that key replacing each occurrence with successive elements
of the key's value.
"""
Methodology
Using re.sub seems to be the best approach to string replacement.
Will you ever have a situation where you might wish to ensure that a string being replaced is on a word boundary? In that case you could surround the key with r'\b', but then calling re.escape on the key would not work. So your keys will already need to be regular expressions that do not need escaping. Would it be useful to have an additional argument, e.g. is_regex, that defaults to False but when True means that the keys are already regular expressions that should not be escaped?
Recommendation and Alternatives
I think it's indicative of something being amiss if there are too few values for any key in replacements. Consequently, in your alternative implementation of replace_func my preference would be for you to either raise an Exception or at least issue a warning for this situation.
An alternative would be to provide an extra, optional argument to your function, e.g. strict_mode=True, which causes behavior as just described but when False, issues no warnings or exceptions.
Another alternative is to define the function so that the last replacement value for a key is never popped; there is always at least one element in the value list for any key. This remaining value will be used for all subsequent replacements. In that way, you can replace all occurrences of a string with the same value just by having a replacement list consisting of a single element. The only error situation now would be to define an empty list as the value for a key.
I'm trying to replace the same characters in a list of strings but nothing is happening?
list = ["stacy", "tracy", "kacy"]
newlist=[]
for x in list:
x.replace("cy","fi")
newlist.append(x)
print(newlist)What's wrong here?