Reputation: 85
I have a .csv
file with some data that i would like to change.
It looks like this:
item_name,item_cost,item_priority,item_required,item_completed
item 1,11.21,2,r
item 2,411.21,3,r
item 3,40.0,1,r,c
My code runs most of what i need but i am unsure of how to write back on my .csv
to produce this result
item_name,item_cost,item_priority,item_required,item_completed
item 1,11.21,2,x
item 2,411.21,3,r
item 3,40.0,1,r,c
My code:
print("Enter the item number:")
line_count = 0
marked_item = int(input())
with open("items.csv", 'r') as f:
reader = csv.DictReader(f, delimiter=',')
for line in reader:
if line["item_required"] == 'r':
line_count += 1
if marked_item == line_count:
new_list = line
print(new_list)
for key, value in new_list.items():
if value == "r":
new_list['item_required'] = "x"
print(new_list)
with open("items.csv", 'a') as f:
writer = csv.writer(f)
writer.writerow(new_list.values())
Upvotes: 3
Views: 123
Reputation: 5704
Using pandas
:
import pandas as pd
df = pd.read_csv("items.csv")
print("Enter the item number:")
marked_item = int(input())
df.set_value(marked_item - 1, 'item_required', 'x')
# This is the extra feature you required:
df.set_value(marked_item - 1, 'item_completed', 'c')
df.to_csv("items.csv", index = False)
Result when marked_item = 1:
item_name,item_cost,item_priority,item_required,item_completed
item 1,11.21,2,x,c
item 2,411.21,3,r,
item 3,40.0,1,r,c
Note that according to RFC4180 you should keep the trailing commas.
Upvotes: 1
Reputation: 306
I guess this should do the trick:
file.py
import csv
fieldnames = ["item_name","item_cost","item_priority","item_required","item_completed"]
csvfile = open("items.csv", 'r+')
csvfilewriter = csv.DictWriter(csvfile, fieldnames=fieldnames,dialect='excel', delimiter=',')
csvfilewriter.writeheader()
print("Enter the item number:")
line_count = 0
marked_item = int(input())
with open("items.csv", 'r') as f:
reader = csv.DictReader(f, delimiter=',')
for line in reader:
if line["item_required"] == 'r':
line_count += 1
if marked_item == line_count:
new_list = line
print(new_list)
for key, value in new_list.items():
if value == "r":
new_list['item_required'] = "x"
print(new_list)
csvfilewriter.writerow(new_list)
If you don't want to update the csv but want to write a new one, below is the code:
import csv
fieldnames = ["item_name","item_cost","item_priority","item_required","item_completed"]
csvfile = open("items_new.csv", 'w')
csvfilewriter = csv.DictWriter(csvfile, fieldnames=fieldnames,dialect='excel', delimiter=',')
csvfilewriter.writeheader()
print("Enter the item number:")
line_count = 0
marked_item = int(input())
with open("items.csv", 'r') as f:
reader = csv.DictReader(f, delimiter=',')
for line in reader:
if line["item_required"] == 'r':
line_count += 1
if marked_item == line_count:
new_list = line
print(new_list)
for key, value in new_list.items():
if value == "r":
new_list['item_required'] = "x"
print(new_list)
csvfilewriter.writerow(new_list)
else:
csvfilewriter.writerow(line)
Upvotes: 0
Reputation: 140186
There are several problems here
DictReader
, which is good to read data, but not as good to read and write data as the original file, since dictionaries do not ensure column order (unless you don't care, but most of the time people don't want columns to be swapped). I just read the title, find the index of the column title, and use this index in the rest of the code (no dicts = faster)newline=''
or you get a lot of blank lines (python 3) or "wb"
(python 2)r
to x
at a given row)Here's the fixed code taking all aforementioned remarks into account
EDIT: added the feature you request after: add a c
after x
if not already there, extending the row if needed
import csv
line_count = 0
marked_item = int(input())
with open("items.csv", 'r') as f:
reader = csv.reader(f, delimiter=',')
title = next(reader) # title
idx = title.index("item_required") # index of the column we target
lines=[]
for line in reader:
if line[idx] == 'r':
line_count += 1
if marked_item == line_count:
line[idx] = 'x'
# add 'c' after x (or replace if column exists)
if len(line)>idx+1: # check len
line[idx+1] = 'c'
else:
line.append('c')
lines.append(line)
with open("items.csv", 'w',newline='') as f:
writer = csv.writer(f,delimiter=',')
writer.writerow(title)
writer.writerows(lines)
Upvotes: 1