Changing the middle of strings in a list--I know there is a betterway.

B

Ben

Hello All:

I am new to Python, and I love it!! I am running 2.6 on Windows. I
have a flat text file here is an example of 3 lines with numbers
changed for security:

999999999088869199999999990200810999999
999999999088869199999999990200810999999
999999999088869199999999990200810999999


I want to be able to replace specific slices with other values. My
code below reads a file into a list of strings. Since strings are
immutable I can't assign different values to a specific slice of the
string. How can I accomplish this? I read some posts on string
formatting but I am having trouble seeing how I can use those features
of the language to solve this problem.

The code below just puts an 'R' at the beginning of each line like
this:

R999999999088869199999999990200810999999
R999999999088869199999999990200810999999
R999999999088869199999999990200810999999


But what I want to do is change the middle of the string. Like this:

R999999999088869CHANGED99990200810999999
R999999999088869CHANGED99990200810999999
R999999999088869CHANGED99990200810999999

#My Current Code

# read the data file in as a list
F = open('C:\\path\\to\file', "r")
List = F.readlines()
F.close()

#Loop through the file and format each line
a=len(List)
while a > 0:

List.insert(a,"2")
a=a-1

# write the changed data (list) to a file
FileOut = open("C:\\path\\to\\file", "w")
FileOut.writelines(List)
FileOut.close()

Thanks for any help and thanks for helping us newbies,

-Ben
 
J

J. Cliff Dyer

Hello All:

I am new to Python, and I love it!! I am running 2.6 on Windows. I
have a flat text file here is an example of 3 lines with numbers
changed for security:

999999999088869199999999990200810999999
999999999088869199999999990200810999999
999999999088869199999999990200810999999


I want to be able to replace specific slices with other values. My
code below reads a file into a list of strings. Since strings are
immutable I can't assign different values to a specific slice of the
string. How can I accomplish this? I read some posts on string
formatting but I am having trouble seeing how I can use those features
of the language to solve this problem.

The code below just puts an 'R' at the beginning of each line like
this:

R999999999088869199999999990200810999999
R999999999088869199999999990200810999999
R999999999088869199999999990200810999999


But what I want to do is change the middle of the string. Like this:

R999999999088869CHANGED99990200810999999
R999999999088869CHANGED99990200810999999
R999999999088869CHANGED99990200810999999

Well, it depends on what you want. Do you want to replace by location
or by matched substring? One of the following functions might help.

lines = ['999999999088869199999999990200810999999'
'99999999088869199999999990200810999999'
'9999999088869199999999990200810999999']

def replace_by_location(string, replacement, start, end):
return string[:start] + replacement + string[end:]

def replace_by_match(string, substr, replacement):
return replacement.join(string.split(substr))

location_lines = [replace_by_location(x, 'CHANGED', 15, 22) for x in lines]
match_lines = [replace_by_match(x, '1999999', 'CHANGED') for x in lines]

print location_lines
print match_lines

Cheers,
Cliff
 
B

Ben

Hello All:
I am new to Python, and I love it!! I am running 2.6 on Windows. I
have a flat text file here is an example of 3 lines with numbers
changed for security:

I want to be able to replace specific slices with other values. My
code below reads a file into a list of strings. Since strings are
immutable I can't assign different values to a specific slice of the
string. How can I accomplish this? I read some posts on string
formatting but I am having trouble seeing how I can use those features
of the language to solve this problem.
The code below just puts an 'R' at the beginning of each line like
this:

But what I want to do is change the middle of the string. Like this:
R999999999088869CHANGED99990200810999999
R999999999088869CHANGED99990200810999999
R999999999088869CHANGED99990200810999999

Well, it depends on what you want.  Do you want to replace by location
or by matched substring?  One of the following functions might help.

lines = ['999999999088869199999999990200810999999'
         '99999999088869199999999990200810999999'
         '9999999088869199999999990200810999999']

def replace_by_location(string, replacement, start, end):
    return string[:start] + replacement + string[end:]

def replace_by_match(string, substr, replacement):
    return replacement.join(string.split(substr))

location_lines = [replace_by_location(x, 'CHANGED', 15, 22) for x in lines]
match_lines = [replace_by_match(x, '1999999', 'CHANGED') for x in lines]

print location_lines
print match_lines

Cheers,
Cliff
#My Current Code
# read the data file in as a list
F = open('C:\\path\\to\file', "r")
List = F.readlines()
F.close()
#Loop through the file and format each line
a=len(List)
while a > 0:
    List.insert(a,"2")
    a=a-1
# write the changed data (list) to a file
FileOut = open("C:\\path\\to\\file", "w")
FileOut.writelines(List)
FileOut.close()
Thanks for any help and thanks for helping us newbies,

Thanks for your help, this explains it I needed a little mental jump
start.

-Ben
 
T

Terry Reedy

You probably don't want to use readlines. It is almost always cleaner just
to iterate over the file itself.

You can't change an existing string, but creating a new string isn't
exactly rocket science.

lines = []
for line in F:
modified = line[:16] + "CHANGED" + line[23:]
# or maybe
modified = line.replace("1999999", "CHANGED")
lines.append(modified)
FileOut.writelines(lines)

If you want your program to scale to indefinitely large files, and you
edit each line independently, without using date from other lines, read
a line *and* write the new line immediately

for line in F:
FileOut.write(<modified>)

Where <modified> is one of the suggested expressions, or a temporary
variable calculated on multiple lines.

To edit a line 'in-place', one can use the array module for mutable
array of bytes (or the 3.0 bytearray), but I would only both with
extensive editing.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top