How to delete only one row from a CSV file with python? - python

I'm trying to make a program which stores a list of names in a CSV file, and I'm trying to add a function to delete rows, which isn't working as it deletes everything in the CSV file.
I've tried using writer.writerow(row), which hasn't worked.
memberName = input("Please enter a member's name to be deleted.")
imp = open('mycsv.csv' , 'rb')
out = open('mycsv.csv' , 'wb')
writer = csv.writer(out)
for row in csv.reader(imp):
if row == memberName:
writer.writerow(row)
imp.close()
out.close()
I expected the program to only delete rows which contained memberName, but it deletes every row in the CSV file.
How do I change it to only delete a single row?

You can't write to the same file while reading it. Instead, use another file for output, e.g.:
import csv
member_name = input("Please enter a member's name to be deleted: ")
with open('in_file.csv') as in_file, open('out_file.csv', 'w') as out_file:
reader = csv.reader(in_file)
writer = csv.writer(out_file)
for row in reader:
if member_name not in row: # exclude a specific row
writer.writerow(row)
Alternatively, you could store needed rows in memory and write them back to the input file after resetting the file pointer:
import csv
member_name = input("Please enter a member's name to be deleted: ")
with open('in_file.csv', 'r+') as in_file:
reader = csv.reader(in_file)
rows = [row for row in csv.reader(in_file) if member_name not in row]
in_file.seek(0)
in_file.truncate()
writer = csv.writer(in_file)
writer.writerows(rows)

This worked for me: you could write the contents of the csv file to a list, then edit the list in python, then write the list back to the csv file.
lines = list()
memberName = input("Please enter a member's name to be deleted.")
with open('mycsv.csv', 'r') as readFile:
reader = csv.reader(readFile)
for row in reader:
lines.append(row)
for field in row:
if field == memberName:
lines.remove(row)
with open('mycsv.csv', 'w') as writeFile:
writer = csv.writer(writeFile)
writer.writerows(lines)

Related

post output to new line of text file everytime

everytime i run my code it overwrites to first line of output.txt.
How can i make it so it writes to a new line every time?
def calculate_averages(input_file_name, output_file_name):
with open(input_file_name) as f:
reader = csv.reader(f)
for row in reader:
name = row[0]
these_grades = list()
for grade in row[1:]:
these_grades.append(int(grade))
with open(output_file_name, 'w') as external_file:
print(name, mean(these_grades), end='\n', file=external_file)
external_file.close()
This is happening because you are reopening your file in "w" mode for each row, which will overwrite your file. You can open the file outside of the for loop to avoid this behaviour:
import numpy as np
import csv
def calculate_averages(input_file_name, output_file_name):
with open(input_file_name) as f:
reader = csv.reader(f)
with open(output_file_name, 'w') as external_file:
for row in reader:
name = row[0]
mean_of_grades = np.mean([int(x) for x in row[1:]])
external_file.write(f"{name} {mean_of_grades}\n")
You can use a different mode for this:
Instead of with open(output_file_name, "w") as external_file:,
Use with open(output_file_name, "a") as external_file.
"a" stands for append, which will append the text to the end of the file.
I hope I understood your question right.

When i try to remove a row from the csv the file size is multipliying

I want to create a program which generates numbers from 0 to 100000 and stores it in a file then, remove the numbers i give as input
I have done the code for generating the numbers and storing them in a csv file
import csv
nums = list(range(0,100000))
with open('codes.csv', 'w') as f:
writer = csv.writer(f)
for val in nums:
writer.writerow([val])
and i tried to delete the row i wanted with this
import csv
import os
lines = list()
while True:
members= input("Please enter a number to be deleted: ")
with open('codes.csv', 'r') as readFile:
reader = csv.reader(readFile)
for row in reader:
lines.append(row)
for field in row:
if field == members:
lines.remove(row)
os.remove('codes.csv')
with open('codes.csv', 'a+') as writeFile:
writer = csv.writer(writeFile)
writer.writerows(lines)
but the file size is multiplying each time i remove a number, please help
Add check before appending to your list, something like this should work:
with open('codes.csv', 'r') as readFile:
reader = csv.reader(readFile)
for row in reader:
if all(field != members for field in row):
lines.append(row)
Ps: don't forget to clear lines by adding lines = [] at the beginning of the while loop (I assume you know what you're doing).
There a two problems:
The lines list is never cleared. Whenever a number is entered, everything is written again to lines.
When writing, the file is opened with the a+ attributes, which means "append and update" file.
Try to recreate the list within the outer while loop and override the file contents by opening the file with attribute w, like this:
import csv
import os
while True:
members= input("Please enter a number to be deleted: ")
lines = list()
with open('codes.csv', 'r') as readFile:
reader = csv.reader(readFile)
for row in reader:
lines.append(row)
for field in row:
if field == members:
lines.remove(row)
os.remove('codes.csv')
with open('codes.csv', 'w') as writeFile:
writer = csv.writer(writeFile)
writer.writerows(lines)

Editing CSV row with Python

I'm trying to edit a single row in a csv file. I've got a CSV file that looks like the bellow:
TYPE|FOOD TYPE|FEED TIME|WASH TIME
LION|MEAT|4H|1D
FOX|MEAT|5H|3D
HEN|SEED|6H|6D
FISH|PLANTS|7H|99D
I want to edit the row based on its TYPE. If the user wants to edit the FOX row they only need to type FOX when prompted. The issue I'm facing is that the I can't edit the file for some reason.
My code is bellow, I open the existing db, find the row in question, change it, then write it, along with the other rows, into a temp file that I can overwrite the original with.
def edit_animal_entry(type):
with open(animal_csv, 'r') as file_read:
reader = csv.reader(file_read, delimiter="|")
with open(temp, 'w') as file_write:
writer = csv.writer(file_write)
for row in reader:
print(f"{' | '.join(row)}")
if row[0] == type:
animal_type, animal_food, animal_feed, animal_wash = animal_inputs()
writer.writerow([animal_type, animal_food, (animal_feed+"H"), (animal_wash+"D")])
else:
writer.writerow(row)
shutil.move(temp, animal_csv)
You've 'closed' the read file by stopping the with block before reading anything out of it. Therefore you aren't looping over your input file. A solution would be to open the input and the output file in the same with statement:
def edit_animal_entry(type):
with open(animal_csv, 'r') as file_read, open(temp, 'w') as file_write:
reader = csv.reader(file_read, delimiter="|")
writer = csv.writer(file_write)
for row in reader:
print(f"{' | '.join(row)}")
if row[0] == type:
animal_type, animal_food, animal_feed, animal_wash = animal_inputs()
writer.writerow([animal_type, animal_food, (animal_feed+"H"), (animal_wash+"D")])
else:
writer.writerow(row)
shutil.move(temp, animal_csv)

Python CSV Row Loop

I am very new to Python programming and decided on a small project to learn the language.
Basically I am trying to:
Read the first cell of a CSV file.
Ask if that cell value is "liked".
If liked, write to the column next to the cell on 1., "1".
Else, write "0".
Repeat on next row until end of list.
My code right now:
import csv
reader = csv.reader(open("mylist.csv"), delimiter=',')
data = []
for row in reader:
data.append(row)
ask = (data[0][0])
ans = input("Do you like {}? ".format(ask))
if ans == ("y"):
f = open('mylist.csv', 'r')
reader = csv.reader(f)
data = list(reader)
f.close()
data[0][1] = '1'
my_new_list = open('mylist.csv', 'w', newline='')
csv_writer = csv.writer(my_new_list)
csv_writer.writerows(data)
my_new_list.close()
else:
f = open('mylist.csv', 'r')
reader = csv.reader(f)
data = list(reader)
f.close()
data[0][1] = '0'
my_new_list = open('mylist.csv', 'w', newline='')
csv_writer = csv.writer(my_new_list)
csv_writer.writerows(data)
my_new_list.close()
So basically, I am stuck trying to get the content of the next row.
FYI, I am looking to implement machine learning to this process.
First learning how to do this in a basic manner.
Any help is welcome.
Thank you!
You shouldn't read from and write to the same file/list/dict at the same time. If you do, references to data may change. You can start with something like this for your task. However, note that as the file grows you code becomes slower.
import csv
reader = csv.reader(open("test.csv", 'r'), delimiter=',')
content = []
for row in reader:
item = row[0]
ans = raw_input("Do you like {}? ".format(item))
if ans == 'y':
content.append([item, 1])
else:
content.append([item, 0])
writer = csv.writer(open('test.csv', 'w'))
writer.writerows(content)
In my last work with csv I opened the file so:
import csv
with open(name) as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
data.append(row)
If you want the resultant csv file to contain all of the data from the input file but with the question results added in, you could use something like this.
It will insert you answer (0 or 1) after the first item in each record.
import csv
reader = csv.reader(open("mylist.csv", 'r'), delimiter=',')
data = []
for row in reader:
data.append(row)
for row in data:
ans = raw_input("Do you like {}? ".format(row[0]))
if ans == 'y':
row[1:1] = "1"
else:
row[1:1] = "0"
writer = csv.writer(open('myresult.csv', 'w'))
writer.writerows(data)

(Simple Python) CSV input to usernames

I have a CSV file names.csv
First_name, Last_name
Mike, Hughes
James, Tango
, Stoke
Jack,
....etc
What I want is to be able to take the first letter of the First_name and the full Last_name and output it on screen as usernames but not include the people with First_name and Last_name property's empty. I'm completely stuck any help would be greatly appreciated
import csv
ifile = open('names.csv', "rb")
reader = csv.reader(ifile)
rownum = 0
for row in reader:
if rownum == 0:
header = row
else:
colnum = 0
for col in row:
print '%-8s: %s' % (header[colnum], col)
colnum += 1
rownum += 1
ifile.close()
Attempt #2
import csv
dataFile = open('names.csv','rb')
reader = csv.reader(dataFile)
next(reader, None)
for row in reader:
if (row in reader )
print (row[0])
I haven't saved many attempts because none of them have worked :S
import csv
dataFile = open('names.csv','rb')
reader = csv.reader(dataFile, delimiter=',', quoting=csv.QUOTE_NONE)
for row in reader:
if not row[0] or not row[1]:
continue
print (row[0][0] + row[1]).lower()
Or
import csv
dataFile = open('names.csv','rb')
reader = csv.reader(dataFile, delimiter=',', quoting=csv.QUOTE_NONE)
[(row[0][0] + row[1]).lower() for row in reader if
row[0] and row[1]]
Once you get the text from the .csv you can use the split() function to break up the text by the new lines. Your sample text is a little inconsistent, but if I understand you question correctly you can say
import csv
dataFile = open('names.csv','rb')
reader = csv.reader(dataFile)
reader = reader.split('\n')
for x in reader
print(reader[x])
Or if you want to break it up by commas just replace the '\n' with ','
Maybe like this
from csv import DictReader
with open('names.csv') as f:
dw = DictReader(f, skipinitialspace=True)
fullnames = filter(lambda n: n['First_name'] and n['Last_name'], dw)
for f in fullnames:
print('{}{}'.format(f['First_name'][0], f['Last_name']))
You have headings in your csv so use a DictReader and just filter out those whose with empty first or last names and display the remaining names.

Categories

Resources