How to remove the second line of a CSV file using Python - python

I need to remove the second line of my csv file.
I am using the code below but unfortunately it doesn't work.
data = ""
adresse = "SLV.csv"
if os.path.exists(adresse) :
f = open(adresse,"ab")
writer = csv.writer(f,delimiter = ",")
reader = csv.reader(open(adresse,"rb") , delimiter = ",")
for line in reader:
if reader.line_num == 2:
writer.writerow(line)
f.close()

Since all you want to do is remove the second line, using the csv module is overkill. It doesn't matter if the file is comma separated data or Vogon poetry. Write the front parts, skip the middle part and write the end.
import shutil
# generate test file
with open('x.txt', 'w') as f:
for i in range(10):
f.write('line %d\n' % i)
# skip one line
with open('x.txt','rb') as rd, open('x.txt', 'rb+') as wr:
wr.write(rd.readline())
rd.readline()
shutil.copyfileobj(rd, wr)
wr.truncate()
print open('x.txt').read()

write to a temp file and update the original after:
if os.path.exists(adresse) :
with open(adresse,"r") as f,open("temp.csv" "a+") as temp:
writer = csv.writer(temp,delimiter = ",")
reader = csv.reader(f , delimiter = ",")
for ind, line in enumerate(reader):
if ind == 2:
continue
else:
temp.writerow(line)
temp.seek(0)
with open(adresse,"w") as out:
reader = csv.reader(temp , delimiter = ",")
writer = csv.writer(out,delimiter = ",")
for row in reader:
writer.writerow(line)
If the files can be read into memory just call list on reader and remove the second element:
if os.path.exists(adresse) :
with open(adresse,"r") as f:
reader = list(csv.reader(f , delimiter = ","))
reader.pop(1)
with open(adresse,"w") as out:
writer = csv.writer(out,delimiter = ",")
for row in reader:
writer.writerow(row)

if i understand you correctly you are trying to make a new file and you don't want to insert the line number 2.
if this is your scenario there is a trivial bug in your procedure, that is:
if reader.line_num != 2:
writer.writerow(line)

Here my solution, less code for you to write:
>>> import pyexcel as pe # pip install pyexcel
>>> sheet = pe.load("SLV.csv")
>>> del sheet.row[1] # first row starts at index 0
>>> sheet.save_as("SLV.csv")

I do agree with tdelaney, and this is a far more compact solution
lines = open('x.txt', 'r').readlines()
lines.pop(1)
open('x.txt', 'w').writelines(lines)

Related

How can i find a specific part of a string?

Im accessing a csv file, looping through all of its rows(strings) and i want too keep / print all parts of each string which start with a "." , has two words in the middle and ends with either a "." "?" or "!".
For example, if the string was: "This is my new channel. Please subscribe!" i'd only want to keep the ". Please subscribe!"
So far i only have this to show me how many words are inside each string:
with open("data2.csv", encoding="utf-8", newline='') as f:
reader = csv.reader(f)
for row in reader:
rowstr = str(row[1])
res = len(row[1].split())
print(res)
I've tried:
with open("data2.csv", encoding="utf-8", newline='') as f:
reader = csv.reader(f)
for row in reader:
rowstr = row[1]
res = len(row[1].split())
re.findall(r"\.\S+\s\S+[.?!]", rowstr)
print(row[1])
I get no output from findall, only from printing row[1]
Fixed it
Working code:
with open("data2.csv", encoding="utf-8", newline='') as f:
reader = csv.reader(f)
for row in reader:
rowstr = row[1]
res = len(row[1].split())
finalData = re.findall(r"(\.\W\w+\W\w+[\.\?!])", rowstr)
print(finalData)
You can use regular expression:
re.findall(r'(\.\W\w+\W\w+[\.\?!])$',"This is my new channel. Please subscribe!" )
which output:
['. Please subscribe!']
Regex is the best solution to the problems like this. Please refer here here!

how to .writerow() to only 1 row in csv file?

Currently in my code it changes the 3rd row but for all rows, I want it to only change the row with the entered GTIN by the user.
Current code:
file=open("stock.csv")
stockfile= csv.reader(file)
for line in stockfile:
if GTIN in line:
currentstock= line[2]
targetstock = line[3]
newstock = (int(currentstock) - int(Quantity))
currentstock = str(currentstock)
targetstock = str(targetstock)
newstock = str(newstock)
if newstock < targetstock :
import csv
reader = csv.reader(open('stock.csv',"r"))
new = csv.writer(open('out.csv',"w"))
for line in reader:
new.writerow([line[0], line[1], newstock , line[3]])
Output in file (it changes all numbers in 3rd column):
86947367,banana,1,40
78364721,apple,1,20
35619833,orange,1,30
84716491,sweets,1,90
46389121,chicken,1,10
How can I only change the row with the GTIN the user enters?
use the csv module:
https://docs.python.org/3/library/csv.html
It has a csv.reader() and csv.writer(). Read the file into memory, iterate over it doing calcs/replacements, then write each row to a new list. Finally, generate a new data file to replace the old one.
I answered one of your other questions before you were using csvreader but it looks like it got deleted. But the principle is the same. As I stated in one of the comments, I don't think you should keep reopening/rereading stock.txt. Just read it line by line then write line by line to an output file:
stock_number = input('Enter the stock number: ')
new_item = input('Enter item to add to above stock listing: ')
lines = []
with open('stock.txt', 'r') as infile:
for line in infile:
lines.append(line)
# can call this 'output.txt' if you don't want to overwrite original
with open('stock.txt', 'w') as outfile:
for line in lines:
if stock_number in line:
# strip newline, add new item, add newline
line = '{},{}\n'.format(line.strip(), new_item)
outfile.write(line)
Edit: here it is with csv module instead. This makes it a little more straightforward because the csv module gives you a list of strings for each line, then you can add to or modify them as desired. Then you can just write the list back line by line, without worrying about newlines or delimiters.
import csv
stock_number = input('Enter the stock number: ')
new_item = input('Enter item to add to above stock listing: ')
lines = []
with open('stock.txt', 'r') as infile:
for line in csv.reader(infile):
lines.append(line)
# change this to 'stock.txt' to overwrite original file
with open('output.txt', 'w') as outfile:
writer = csv.writer(outfile)
for line in lines:
if stock_number in line:
line.append(new_item)
writer.writerow(line)
Also you shouldn't really import anything in the middle of the code like that. Imports generally go at the top of your file.

python 3 csv reader + Ignore empty records [duplicate]

This is my code i am able to print each line but when blank line appears it prints ; because of CSV file format, so i want to skip when blank line appears
import csv
import time
ifile = open ("C:\Users\BKA4ABT\Desktop\Test_Specification\RDBI.csv", "rb")
for line in csv.reader(ifile):
if not line:
empty_lines += 1
continue
print line
If you want to skip all whitespace lines, you should use this test: ' '.isspace().
Since you may want to do something more complicated than just printing the non-blank lines to the console(no need to use CSV module for that), here is an example that involves a DictReader:
#!/usr/bin/env python
# Tested with Python 2.7
# I prefer this style of importing - hides the csv module
# in case you do from this_file.py import * inside of __init__.py
import csv as _csv
# Real comments are more complicated ...
def is_comment(line):
return line.startswith('#')
# Kind of sily wrapper
def is_whitespace(line):
return line.isspace()
def iter_filtered(in_file, *filters):
for line in in_file:
if not any(fltr(line) for fltr in filters):
yield line
# A dis-advantage of this approach is that it requires storing rows in RAM
# However, the largest CSV files I worked with were all under 100 Mb
def read_and_filter_csv(csv_path, *filters):
with open(csv_path, 'rb') as fin:
iter_clean_lines = iter_filtered(fin, *filters)
reader = _csv.DictReader(iter_clean_lines, delimiter=';')
return [row for row in reader]
# Stores all processed lines in RAM
def main_v1(csv_path):
for row in read_and_filter_csv(csv_path, is_comment, is_whitespace):
print(row) # Or do something else with it
# Simpler, less refactored version, does not use with
def main_v2(csv_path):
try:
fin = open(csv_path, 'rb')
reader = _csv.DictReader((line for line in fin if not
line.startswith('#') and not line.isspace()),
delimiter=';')
for row in reader:
print(row) # Or do something else with it
finally:
fin.close()
if __name__ == '__main__':
csv_path = "C:\Users\BKA4ABT\Desktop\Test_Specification\RDBI.csv"
main_v1(csv_path)
print('\n'*3)
main_v2(csv_path)
Instead of
if not line:
This should work:
if not ''.join(line).strip():
my suggestion would be to just use the csv reader who can delimite the file into rows. Like this you can just check whether the row is empty and if so just continue.
import csv
with open('some.csv', 'r') as csvfile:
# the delimiter depends on how your CSV seperates values
csvReader = csv.reader(csvfile, delimiter = '\t')
for row in csvReader:
# check if row is empty
if not (row):
continue
You can always check for the number of comma separated values. It seems to be much more productive and efficient.
When reading the lines iteratively, as these are a list of comma separated values you would be getting a list object. So if there is no element (blank link), then we can make it skip.
with open(filename) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=",")
for row in csv_reader:
if len(row) == 0:
continue
You can strip leading and trailing whitespace, and if the length is zero after that the line is empty.
import csv
with open('userlist.csv') as f:
reader = csv.reader(f)
user_header = next(reader) # Add this line if there the header is
user_list = [] # Create a new user list for input
for row in reader:
if any(row): # Pick up the non-blank row of list
print (row) # Just for verification
user_list.append(row) # Compose all the rest data into the list
This example just prints the data in array form while skipping the empty lines:
import csv
file = open("data.csv", "r")
data = csv.reader(file)
for line in data:
if line: print line
file.close()
I find it much clearer than the other provided examples.
import csv
ifile=csv.reader(open('C:\Users\BKA4ABT\Desktop\Test_Specification\RDBI.csv', 'rb'),delimiter=';')
for line in ifile:
if set(line).pop()=='':
pass
else:
for cell_value in line:
print cell_value

how to skip blank line while reading CSV file using python

This is my code i am able to print each line but when blank line appears it prints ; because of CSV file format, so i want to skip when blank line appears
import csv
import time
ifile = open ("C:\Users\BKA4ABT\Desktop\Test_Specification\RDBI.csv", "rb")
for line in csv.reader(ifile):
if not line:
empty_lines += 1
continue
print line
If you want to skip all whitespace lines, you should use this test: ' '.isspace().
Since you may want to do something more complicated than just printing the non-blank lines to the console(no need to use CSV module for that), here is an example that involves a DictReader:
#!/usr/bin/env python
# Tested with Python 2.7
# I prefer this style of importing - hides the csv module
# in case you do from this_file.py import * inside of __init__.py
import csv as _csv
# Real comments are more complicated ...
def is_comment(line):
return line.startswith('#')
# Kind of sily wrapper
def is_whitespace(line):
return line.isspace()
def iter_filtered(in_file, *filters):
for line in in_file:
if not any(fltr(line) for fltr in filters):
yield line
# A dis-advantage of this approach is that it requires storing rows in RAM
# However, the largest CSV files I worked with were all under 100 Mb
def read_and_filter_csv(csv_path, *filters):
with open(csv_path, 'rb') as fin:
iter_clean_lines = iter_filtered(fin, *filters)
reader = _csv.DictReader(iter_clean_lines, delimiter=';')
return [row for row in reader]
# Stores all processed lines in RAM
def main_v1(csv_path):
for row in read_and_filter_csv(csv_path, is_comment, is_whitespace):
print(row) # Or do something else with it
# Simpler, less refactored version, does not use with
def main_v2(csv_path):
try:
fin = open(csv_path, 'rb')
reader = _csv.DictReader((line for line in fin if not
line.startswith('#') and not line.isspace()),
delimiter=';')
for row in reader:
print(row) # Or do something else with it
finally:
fin.close()
if __name__ == '__main__':
csv_path = "C:\Users\BKA4ABT\Desktop\Test_Specification\RDBI.csv"
main_v1(csv_path)
print('\n'*3)
main_v2(csv_path)
Instead of
if not line:
This should work:
if not ''.join(line).strip():
my suggestion would be to just use the csv reader who can delimite the file into rows. Like this you can just check whether the row is empty and if so just continue.
import csv
with open('some.csv', 'r') as csvfile:
# the delimiter depends on how your CSV seperates values
csvReader = csv.reader(csvfile, delimiter = '\t')
for row in csvReader:
# check if row is empty
if not (row):
continue
You can always check for the number of comma separated values. It seems to be much more productive and efficient.
When reading the lines iteratively, as these are a list of comma separated values you would be getting a list object. So if there is no element (blank link), then we can make it skip.
with open(filename) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=",")
for row in csv_reader:
if len(row) == 0:
continue
You can strip leading and trailing whitespace, and if the length is zero after that the line is empty.
import csv
with open('userlist.csv') as f:
reader = csv.reader(f)
user_header = next(reader) # Add this line if there the header is
user_list = [] # Create a new user list for input
for row in reader:
if any(row): # Pick up the non-blank row of list
print (row) # Just for verification
user_list.append(row) # Compose all the rest data into the list
This example just prints the data in array form while skipping the empty lines:
import csv
file = open("data.csv", "r")
data = csv.reader(file)
for line in data:
if line: print line
file.close()
I find it much clearer than the other provided examples.
import csv
ifile=csv.reader(open('C:\Users\BKA4ABT\Desktop\Test_Specification\RDBI.csv', 'rb'),delimiter=';')
for line in ifile:
if set(line).pop()=='':
pass
else:
for cell_value in line:
print cell_value

Read a CSV file and put double quote on each item in python

I'm really new to python and I have a simple question. I have a .csv file with the following content:
123,456,789
I want to read it and store it into a variable called "number" with the following format
"123","456","789"
So that when I do
print number
It will give the following output
"123","456","789"
Can anybody help?
Thanks!
Update:
The following is my code:
input = csv.reader(open('inputfile.csv', 'r'))
for item in input:
item = ['"' + item + '"' for item in item]
print item
It gave the following output:
['"123"', '"456"', '"789"']
Here's how to do it:
import csv
from io import StringIO
quotedData = StringIO()
with open('file.csv') as f:
reader = csv.reader(f)
writer = csv.writer(quotedData, quoting=csv.QUOTE_ALL)
for row in reader:
writer.writerow(row)
with reader=csv.reader(StringIO('1,2,3')) the output is:
print quotedData.getvalue()
"1","2","3"
Using the csv-module, you can read the .csv file line-by-line and process each element from a tuple you gain. You can then just enclose each element into double-quotes.
import csv
reader = csv.reader(open("file.csv"))
for line in reader:
# line is a tuple ...
If the whole file only contains numbers you can just open it as a regular file:
with open("file.csv") as f:
for line in f:
print ','.join('"{}"'.format(x) for x in line.rstrip().split(','))
It'd be better to append the lines to an array with append, tho. For example:
with open("file.csv") as f:
lines=[line.rstrip().split(',') for line in f]
There is a CSV module there that might help you as well.
import csv
spamReader = csv.reader(open('eggs.csv', 'rb'))
for row in spamReader:
this_row = ['"' + str(item) + '"' for item in row]
print this_row
import csv
csvr = csv.reader(open(<yourfile.csv>,'r'))
def gimenumbers():
for row in csvr:
yield '","'.join(row)

Categories