Append string to previous line if certain condition in python - python

I have csv file with single column, in some cases the last value gets more space and create new row, here I need to find out and append it to the previous line
for eg :
my python code :
with open("01.csv", 'r+') as file:
text = str()
for line in file:
if line[0:3] == "2021":
text = "{} {}".format(text, line.strip())
else:
text = "{}\n{}".format(text, line.strip())
file.seek(0)
file.write(text[1:])
How to remove || this in last and append next line to it in all occurrence.
Line no 10 to be appended to line no 9 and line no 21 to be appended to line no 20 nd so on..

You can't "append next line" if you haven't seen it yet. Your solution has to know that all appends are complete before otherwise acting on a line, which means you need to buffer the next line.
I think you're trying to re-compose the whole file in text as you go, which isn't a great model for file handling. And if your test were working, the actions are actually the wrong way around - you want to include the newline when "20" starts the line. I suggest that instead you write to another new file or simply correct the issue on the fly as below.
with open("01.csv", 'r+') as file:
complete_line = None
for line in file:
if complete_line is None:
initial_action()
complete_line = line
elif line[0:2] == "20": # compatible with next 79 years
act_on(complete_line)
complete_line = line
else:
complete_line += line
act_on(complete_line)
where intial_action and act_on are functions for you to implement.

Related

How to read a file from one line to the end and write another from that same line to the end?

print("Type: \n 1 - To read and translate from the beginning of the file\n 2 - To read from a specific line of the file")
how_to_read = str(input())
if (how_to_read == "1"):
read_mode = "w"
total_previous_lines = 0 #Read the file from the beginning
elif(how_to_read == "2"):
read_mode = "a"
with open('translated_file.xml') as last_translated_file:
total_previous_lines = sum(1 for line in last_translated_file) - 1 #Number of lines, to which one is subtracted for the last line that is empty and must be replaced from it if it is the case
print(total_previous_lines)
else:
print("You have not chosen any of the valid options")
read_mode = None
if(read_mode):
with open("en-sentiment.xml", "r") as read_file:
#I NEED TO READ "en-sentiment.xml" FROM total_previous_lines + 1 (that is, the next to the last one that already existed, to continue...)
with open("translated_file.xml", read_mode) as write_file:
# I NEED TO WRITE "translated_file.xml" FROM total_previous_lines + 1 (ie the next to the last one, to continue...)
#For each line of the file that it reads, we will write the file with the write function.
for line in read_file:
print(repr(line))
That's my code, and I was having trouble reading the .xml files from that total_previous_lines, since the statement with open() as ..._file: naturally reads from the beginning iterating line by line, but in this case if the file already existed, if with the opening mode a you wanted to write from total_previous_lines you would have the problem that it starts to iterate from the beginning.
And with the opening mode "r" the same thing would happen if you want to read from total_previous_lines with a value other than 0 (that is, the first line)
Ignoring the code in your question...
Let's say that by some means or other you have figured out a line in your input file that you want to start reading from and that you want to copy the remainder of that input file to some other file.
start_line = 20 # for example
with open('input_file.txt') as infile:
with open('output_file.txt', 'w') as outfile:
for line in infile.readlines()[start_line:]:
outfile.write(line)
Read about seek() in python. But better use an xml parser like ElementTree.

I have a problem adding string from a .txt file to a list, even after trying to use .append

The program reads in a line like "Joe:100" and it splits it in the middle, it's then supposed to place the name into one list and the number it another.
Here is what I have:
def splitData(num,person):
counter = 0
with open ("Data.txt") as file_object:
for line in file_object:
line = file_object.readline()
words = line.split(":")
num.append(words[1])
person.append(words[0])
I feel like I'm close to getting it right but then again I could be miles off.
for line in file_object:
line = file_object.readline()
These 2 lines both read a line, so every iteration you are skipping a line.
for line in file_object: is all you need to read a file line by line.
You will also probably want to do line.strip() to remove the newline character at the end of your numbers

Trying to delete lines in a text file that contain a specific character

I'm testing the code below, but it doensn't do what I would like it to do.
delete_if = ['#', ' ']
with open('C:\\my_path\\AllDataFinal.txt') as oldfile, open('C:\\my_path\\AllDataFinalFinal.txt', 'w') as newfile:
for line in oldfile:
if not any(del_it in line for del_it in delete_if):
newfile.write(line)
print('DONE!!')
Basically, I want to delete any line that contains a '#' character (the lines I want to delete start with a '#' character). Also, I want to delete any/all lines that are completely blank. Can I do this in on go, by reading through items in a list, or will it require several passes through the text file to clean up everything? TIA.
It's easy. Check my code below :
filePath = "your old file path"
newFilePath = "your new file path"
# we are going to list down which lines start with "#" or just blank
marker = []
with open(filePath, "r") as file:
content = file.readlines() # read all lines and store them into list
for i in range(len(content)): # loop into the list
if content[i][0] == "#" or content[i] == "\n": # check if the line starts with "#" or just blank
marker.append(i) # store the index into marker list
with open(newFilePath, "a") as file:
for i in range(len(content)): # loop into the list
if not i in marker: # if the index is not in marker list, then continue writing into file
file.writelines(content[i]) # writing lines into file
The point is, we need to read all the lines first. And check line by line whether it starts with # or it's just blank. If yes, then store it into a list variable. After that, we can continue writing into new file by checking if the index of the line is in marker or not.
Let me know if you have problem.
How about using the ternary operator?
#First option: within your for loop
line = "" if "#" in line or not line else line
#Second option: with list comprehension
newFile = ["" if not line or "#" in line else line for line in oldfile]
I'm not sure if the ternary would work because if the string is empty, an Exception should be shown because "#" won't be in an empty string... How about
#Third option: "Staging your conditions" within your for loop
#First, make sure the string is not empty
if line:
#If it has the "#" char in it, delete it
if "#" in line:
line = ""
#If it is, delete it
else:
line = ""

break when empty line from a File

I have file contains text like Hello:World
#!/usr/bin/python
f = open('m.txt')
while True:
line = f.readline()
if not line :
break
first = line.split(':')[0]
second = line.split(':')[1]
f.close()
I want to put the string after splitting it into 2 variables
On the second iteration i get error
List index out of range
it doesn't break when the line is empty , i searched the answer on related topics and the solution was
if not line:
print break
But it does not work
If there's lines after an empty line (or your text editor inserted an empty line at the end of the file), it's not actually empty. It has a new line character and/or carriage return
You need to strip it off
with open('m.txt') as f:
for line in f:
if not line.strip():
break
first, second = line.split(':')
You can do this relatively easily by utilizing an optional feature of the built-in iter() function by passing it a second argument (called sentinel in the docs) that will cause it to stop if the value is encountered while iterating.
Here's what how use it to make the line processing loop terminate if an empty line is encountered:
with open('m.txt') as fp:
for line in iter(fp.readline, ''):
first, second = line.rstrip().split(':')
print(first, second)
Note the rstrip() which removes the newline at the end of each line read.
Your code is fine, I can't put a picture in a comment. It all works, here:

Printing to a file via Python

Hopefully this is an easy fix. I'm trying to edit one field of a file we use for import, however when I run the following code it leaves the file blank and 0kb. Could anyone advise what I'm doing wrong?
import re #import regex so we can use the commands
name = raw_input("Enter filename:") #prompt for file name, press enter to just open test.nhi
if len(name) < 1 : name = "test.nhi"
count = 0
fhand = open(name, 'w+')
for line in fhand:
words = line.split(',') #obtain individual words by using split
words[34] = re.sub(r'\D', "", words[34]) #remove non-numeric chars from string using regex
if len(words[34]) < 1 : continue # If the 34th field is blank go to the next line
elif len(words[34]) == 2 : "{0:0>3}".format([words[34]]) #Add leading zeroes depending on the length of the field
elif len(words[34]) == 3 : "{0:0>2}".format([words[34]])
elif len(words[34]) == 4 : "{0:0>1}".format([words[34]])
fhand.write(words) #write the line
fhand.close() # Close the file after the loop ends
I have taken below text in 'a.txt' as input and modified your code. Please check if it's work for you.
#Intial Content of a.txt
This,program,is,Java,program
This,program,is,12Python,programs
Modified code as follow:
import re
#Reading from file and updating values
fhand = open('a.txt', 'r')
tmp_list=[]
for line in fhand:
#Split line using ','
words = line.split(',')
#Remove non-numeric chars from 34th string using regex
words[3] = re.sub(r'\D', "", words[3])
#Update the 3rd string
# If the 3rd field is blank go to the next line
if len(words[3]) < 1 :
#Removed continue it from here we need to reconstruct the original line and write it to file
print "Field empty.Continue..."
elif len(words[3]) >= 1 and len(words[3]) < 5 :
#format won't add leading zeros. zfill(5) will add required number of leading zeros depending on the length of word[3].
words[3]=words[3].zfill(5)
#After updating 3rd value in words list, again creating a line out of it.
tmp_str = ",".join(words)
tmp_list.append(tmp_str)
fhand.close()
#Writing to same file
whand = open("a.txt",'w')
for val in tmp_list:
whand.write(val)
whand.close()
File content after running code
This,program,is,,program
This,program,is,00012,programs
The file mode 'w+' Truncates your file to 0 bytes, so you'll only be able to read lines that you've written.
Look at Confused by python file mode "w+" for more information.
An idea would be to read the whole file first, close it, and re-open it to write files in it.
Not sure which OS you're on but I think reading and writing to the same file has undefined behaviour.
I guess internally the file object holds the position (try fhand.tell() to see where it is). You could probably adjust it back and forth as you went using fhand.seek(last_read_position) but really that's asking for trouble.
Also, I'm not sure how the script would ever end as it would end up reading the stuff it had just written (in a sort of infinite loop).
Best bet is to read the entire file first:
with open(name, 'r') as f:
lines = f.read().splitlines()
with open(name, 'w') as f:
for l in lines:
# ....
f.write(something)
For 'Printing to a file via Python' you can use:
ifile = open("test.txt","r")
print("Some text...", file = ifile)

Categories

Resources