Replace character in list a with character from list b

I have two text files:

clues.txt - contains letter / character pairs:

A#
M*
N%

      

words.txt - contains a list of the scrambled words:

#+/084&"
#3*#%#+
8%203:
,1$&
!-*%
.#7&33&
#*#71%
&-&641'2
#))85
9&330*

      

I read the contents of each file in a list using lists:

clues = [line.strip() for line in open("clues.txt", 'r')]

words = [line.strip() for line in open("words.txt", 'r')]

      

How would I dynamically replace all instances of each character in the list words

with the corresponding character from the list clues

?

So, each instance #

in words

is replaced by A

, each instance *

in words

is replaced by M

, etc.

+3


source to share


4 answers


You can use str.replace

generating pairs of substrings from each string in the keys and then looping over the reassignment of the string to the updated string value after the replacement:

with  open("clues.txt", 'r') as f, open("words.txt", 'r') as f2:
    clues = [list(line.rstrip()) for line in f]
    for line in f2:
        for rep, orig in clues:
            line = line.replace(orig, rep)
        print(line.rstrip())

      

Output:



A+/084&"
A3MANA+
8N203:
,1$&
!-MN
.A7&33&
AMA71N
&-&641'2
A))85
9&330M

      

Or use str.translate :

with  open("clues.txt", 'r') as f, open("words.txt", 'r') as f2:
    # keys are ord of character to replace, 
    # values are character to replace with
    d = {ord(k): v for v, k in (list(line.rstrip()) for line in f)}
    for line in f2:
        print(line.translate(d).rstrip())

      

Output:



A+/084&"
A3MANA+
8N203:
,1$&
!-MN
.A7&33&
AMA71N
&-&641'2
A))85
9&330M

      

For python2, you need to use string.maketrans

to create the table:

from string import maketrans
with open("clues.txt", 'r') as f, open("words.txt", 'r') as f2:
    # separate A -> # ...
    a, b = zip(*(list(line.rstrip()) for line in f))
    # create table where # maps to A, * -> M and % -> N
    tbl = maketrans("".join(b), "".join(a))
    for line in f2:
        # translate each string using our mapping table
        print(line.translate(tbl).rstrip())

      

Output:



A+/084&"
A3MANA+
8N203:
,1$&
!-MN
.A7&33&
AMA71N
&-&641'2
A))85
9&330M

      

Python3 requires matching the character of the ord

character to replace with the string you want to replace, in python 2 we do something similar but have to use string.maketrans to create our table that ends as strings '#*%', 'AMN'

.

+4


source


The most efficient way to do this is to use string.translate

:



 
import string

with open('clues.txt', 'r') as cluesf, open('words.txt', 'r') as wordsf:
    clues = [line.strip() for line in cluesf]
    trans = string.maketrans(''.join([c[1:] for c in clues]), ''.join([c[0] for c in clues]))
    words = [line.strip().translate(trans) for line in wordsf]

    print(words)

      

+1


source


There are many ways to do this, and there may be various restrictions. As is the size of the word file, regardless of whether the hints are always 2 characters, with the 1st character being replaced and the second character to be replaced. Here is a simple solution you can use.

Instead of reading the words in the list, read it as a string first (assuming a file of a reasonable size) and then replace it with your hints and split it after that. So you can only have replacements once per key. How:

with open('words.txt') as wfd: file_as_string = wfd.read()
for clue in clues: words_str = file_as_string.replace(clue[1], clue[0])
words = [word.strip() for word in file_as_string.split('\n')]

      

0


source


First convert clues

to display of actual key / value pairs:

clues = [line.strip() for line in open("clues.txt", 'r')]
clues = dict([(k, v) for v, k in clues])

      

Then we iterate over every character of every word in words

:

for word in words:
    for i, c in enumerate(word):
        if c in clues:
            word[i] = clues[c]

      

Unfortunately, this is not the most efficient and at worst complexity O^2

.

Update: Improved version:

clues = dict([(k, v) for v, k in map(str.strip, open("clues.txt", "r"))])
with open("words.txt", "r") as f:
    for i, c in enumerate(word):
        if c in clues:
            word[i] = clues[c]

      

0


source







All Articles