why does name get replaced by only the first name in the list?

30 views Asked by At
with open("./Input/Names/invited_names.txt") as f:
    names = f.readlines()

with open("./Input/Letters/starting_letter.txt", mode="r+") as f:
    letter = f.read()
    for name in names:
        letter = letter.replace("[name]", name)
        f.write(letter)

I am trying to replace the string [name] with actual names stored in a list. The problem is that in all iterations only the first name is replacing the [name] string.

2

There are 2 answers

0
HarryFoster1812 On

Your question is not very clear, it would be more helpful if you provided the contents of the files.

I think your issue is that when you initilise letter it is stored as a string and when you use the .replace() method all of the instances are being replaced on the first iteration of the loop. On the next iteration, all of the instances are already replaced so the .replace() method will do nothing.

The .replace() function has an overload where you can specify the maximum amount of occurrences to replace so instead of letter = letter.replace("[name]", name) you should use letter = letter.replace("[name]", name, 1)

0
brillenheini On
from strings import Template

with open("./Input/Names/invited_names.txt") as f:
    names = f.readlines()

with open("./Input/Letters/template_starting_letter.txt") as f:
    letter_tmpl = f.read()

tmpl = Template(letter_tmpl)

with open("./Input/Letters/starting_letter.txt", "w+") as f_out:
    for name in names:
        letter = tmpl.safe_substitute(name=name)
        f.write(letter)

It's not the best idea to use letter several times for different tasks. In your case you replace something in letter and assign it to letter. The next thing is that string.replace('pattern', value) is done over all occurances, not only the first one. Means that once replaces [name] won't exist anymore.

A much better idea would be creating a template with the variable ${name} somewhere and use Template from the strings library. In this case you can loop over all names, take the template, substitute the variable and append the final text to some output file.

Not tested, but should work.