GhostShadow
GhostShadow

Reputation: 9

Function to replace multiple characters

My code:

def replaces(_str:str,a=list,b=list):
    output = ''
    for num,i in enumerate(_str):
        output += i.replace(a[num],b[num])
    return output

but it outputs this:

>>> print(replaces('12345',['1','2','3'],['one','two','three']))
Traceback (most recent call last):
  File "g:\+ Project\beat_machine\test.py", line 7, in <module>
    text = replaces('12345',['1','2','3'],['one','two','three'])
  File "g:\+ Project\beat_machine\test.py", line 4, in replaces
    output += i.replace(a[num],b[num])
IndexError: list index out of range

How to fix this?

Upvotes: 0

Views: 464

Answers (4)

Dmitriy Neledva
Dmitriy Neledva

Reputation: 864

def replaces(s:str,a=list,b=list)->str:
    return " ".join([dict(zip(a,b)).get(i,i) for i in s.split()]) if ' ' in s else "".join([dict(zip(a,b)).get(i,i) for i in s])  

print(replaces('one two three four five',['one','two','three'],['1','2','3']))      # 1 2 3 four five
print(replaces('12345',['1','2','3'],['one','two','three']))                        # onetwothree45 

Upvotes: 0

furas
furas

Reputation: 142631

You should rather use zip(a,b) to crete pairs and use these paris in replace()

def replaces(_str:str, a=list, b=list):
    output = _str
    for old_item, new_item in zip(a, b):
        output = output.replace(old_item, new_item)
    return output

print(replaces('12345',['1','2','3'],['one','two','three']))

Or you could create dictionary {'1': 'one', '2': 'two', '3': 'three'} and later use .get(key, default) with old value as default

def replaces(_str:str, a=list, b=list):

    data = dict(zip(a, b))
    
    output = ""
    for old_item in _str:
        new_item = data.get(old_item, old_item)
        output += new_item
    return output

print(replaces('12345',['1','2','3'],['one','two','three']))

It similar to

    for old_item in _str:
        if old_item in data:
            new_item = data[old_item]
        else:
            new_item = old_item
        output += new_item

Upvotes: 1

amirhm
amirhm

Reputation: 1249

You could generate a dictionary or table and use the translate to convert your string.

def replaces(_str:str, a=list, b=list):
    trans = {ord(k):v for k, v in  zip(a, b)}
    return _str.translate(trans)

Upvotes: 1

blhsing
blhsing

Reputation: 106445

To map a set of strings to a different set of strings, it would be easiest to create a mapping dict and use re.sub with all the source strings joined into an alternation pattern and with a replacement function that returns the mapped value of each match:

import re

def replaces(s, a, b):
    mapping = dict(zip(a, b))
    return re.sub('|'.join(map(re.escape, a)), lambda m: mapping[m[0]], s)

so that:

print(replaces('12345',['1','2','3'],['one','two','three']))

outputs:

onetwothree45

Demo: https://replit.com/@blhsing/PlumpGrossManagement

Upvotes: 1

Related Questions