Reputation: 61
I want to find and replace floats with integers in several text files.
There is one float value per text file which I want to convert. It is always after a specific keyword and has to be multiplied by 10.000.
e.g. the float 1.5 should be turned into the integer 15.000
The other floats after 1.5 don't have to be changed though
def edit(file):
with open(file, 'r') as f:
filedata = f.read()
for line in filedata:
if "keyword" in line:
filedata = filedata.replace(re.search(r"\d+\.\d+", line).group(), str(10000*re.search(r"\d+\.\d+", line).group()))
with open(file, 'w') as f:
f.write(filedata)
I was trying to replace the the float using a regex. But this doesn't work
EXAMPLE FILE EXTRACT
abcdef 178 211 208 220
ghijkl 0 0 0 0
keyword 1.50 1.63 1.56 1.45
Upvotes: 2
Views: 498
Reputation: 2123
You can iterate over lines with lines = filedata.split("\n")
. Be careful because filedata
is a big string containing the whole file. When you did for line in filedata
, you iterated over every character of the file...
I also used another way (without regex
) to find numbers and change them.
def edit(file):
with open(file, "r") as f:
filedata = f.read()
lines = filedata.split("\n") # list of lines
for index, line in enumerate(lines):
if "keyword" in line:
words = line.split() # ['keyword', '1.50', '1.63', '1.56', '1.45']
for i, w in enumerate(words):
try:
# transform number to float, multiply by 10000
# then transform to integer, then back to string
new_word = str(int(float(w)*10000))
words[i] = new_word
except:
pass
lines[index] = " ".join(words)
new_data = "\n".join(lines) # store new data to overwrite file
with open(file, "w") as f: # open file with write permission
f.write(new_data) # overwrite the file with our modified data
edit("myfile.txt")
Output :
# myfile.txt
abcdef 178 211 208 220
ghijkl 0 0 0 0
keyword 15000 16299 15600 14500
EDIT : More Compact way
def edit(file):
with open(file, "r") as f:
filedata = f.read()
line = [x for x in filedata.split("\n") if "keyword" in x][0]
new_line = line
for word in line.split():
try: new_line = new_line.replace(word, str(int(float(word)*10000)))
except: pass
with open(file, "w") as f: # open file with write permission
f.write(filedata.replace(line, new_line)) # overwrite the file with our modified data
edit("myfile.txt")
Upvotes: 1
Reputation: 149025
When you find yourself using a regex inside a loop, you should compile it ouside of the loop.
Next, if you want to replace a value in a line, you should not search for it in the whole file.
Finally you must cast a string to a numeric type to operate on it. If you do not you will just repeat the string ('10' * 2
is '1010'
not 20
nor '20'
)
Here is a possible improvement of your code:
def edit(file):
with open(file, 'r') as f:
rx = re.compile(r"\d+\.\d+") # compile the regex only once
filedata = f.readlines() # get a list of the lines of the file
for i, line in enumerate(filedata): # and enumerate them
if "keyword" in line:
val = re.search(r"\d+\.\d+", line).group() # split the complex line
newval = str(int(float(val) * 10000))
filedata[i] = line.replace(val, newval) # replace only the current line
break # no need to proceed further
with open(file, 'w') as f:
f.write(filedata)
Upvotes: 1