Reputation: 13
I have a string and 2 arrays like below:
st="a1b2c3d"
arr1 = ['1','2','3']
arr2 = ['X','Y','Z']
I want to replace all the value of '1', '2', '3' to 'X', 'Y', 'Z'. The final string will look like:
'aXbYcZd'
So I wrote this for loop:
for i in range(0, len(arr1)):
st.replace(str(arr1[i]),str(arr2[i]))
The result is:
'aXb2c3d'
'a1bYc3d'
'a1b2cZd'
How to correctly do what I want above?
Thanks!
Upvotes: 1
Views: 1221
Reputation: 134066
If you're replacing characters, instead of the inefficient replace loop use str.translate
with str.maketrans
:
>>> table = str.maketrans('123', 'XYZ')
>>> result = 'a1b2c3d'.translate(table)
>>> result
'aXbYcZd'
maketrans
requires 2 strings as arguments. If you really have a list, you can use ''.join(l)
to make it into a suitable string. You need to make the table only once.
The efficiency is but one point. str.translate
is the way to do this correctly in cases where you will map a
=> b
and b
=> something else. If you want to replace strings then you might need to use re.sub
instead.
Upvotes: 2
Reputation: 249642
Calling replace over and over means you have to iterate through the entire string for each replacement, which is O(m * n). Instead:
rep = dict(zip(arr1, arr2)) # make mapping, O(m)
result = ''.join(rep.get(ch, ch) for ch in st)
The first line is O(m), where m is the length of arr1 and arr2.
The second line is O(n), where n is the length of st.
In total this is O(m + n) instead of O(m * n), which is a significant win if either m or n is large.
Upvotes: 0
Reputation: 26057
Use zip()
to iterate through two lists simultaneously to replace values:
st = "a1b2c3d"
arr1 = ['1','2','3']
arr2 = ['X','Y','Z']
for x, y in zip(arr1, arr2):
st = st.replace(x, y)
print(st)
# aXbYcZd
str.replace()
does not replace a string in-place. You need to assign returned value back to a variable.
Upvotes: 2