简体   繁体   English

如何更改.csv文件中一行的最后一个值

[英]How to change the last value of a row in .csv file

I'm creating a to-do list using CLI and i want to change the last value of a row ie Status from 'Incomplete' to 'Complete' 我正在使用CLI创建待办事项列表,我想将行的最后一个值(即状态)从“未完成”更改为“完成”

I know that we can't edit a csv file just like that so what we have to do is read it change the value then overwrite the existing file. 我知道我们不能像这样编辑csv文件,因此我们要做的就是读取它更改值,然后覆盖现有文件。 here's the csv file: https://drive.google.com/open?id=1fqc79mtVmZGZ_pb_2zrzDGVDmyMFWi6C I tried this: 这是csv文件: https : //drive.google.com/open? id =1fqc79mtVmZGZ_pb_2zrzDGVDmyMFWi6C我尝试了以下操作:

import csv
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-o', '--option', metavar='', help='-o <option> write either you want to add or view')
parser.add_argument('-l', '--select', metavar='', help='-l <used to select the task for modification')
args = parser.parse_args()


    def modify():
        select = args.select
        with open('csv.csv', 'r+', newline='') as file:
            lines = list(file)
            lines[int(select)][7] = 1
        with open('csv.csv', 'w+', newline='') as ifile:
            writer = csv.writer(ifile)
            writer.writerows(lines)

I want that when we run this: 运行此命令时,我希望这样做:

python todoarg.py -o modify -l 2

it changes the status of 2nd row from 'Incomplete' to 'Complete' 它将第二行的状态从“未完成”更改为“完成”

I found a way to do it without pandas too: 我也找到了一种不用熊猫的方法:

    def modify():
        with open("csv.csv", 'r+') as f:
            lines = f.readlines()
            f.seek(0)

            task = args.select

            for line in lines:
                if not task in line.split(',')[0]:
                    f.write(line)
            for line in lines:
                if task in line.split(',')[0]:
                    #what we do here is print existing values using their index
                    #with split function and adding 'Complete' instead of
                    #6th index which was 'Incomplete'
                    f.write('\n' + line.split(',')[0] + ',' + line.split(',')[1] + ',' + line.split(',')[2] + ','
                            + line.split(',')[3] + ',' + line.split(',')[4] + ','
                            + line.split(',')[5] + ',' + 'Complete')

            f.truncate()

I know this is a newb way but it works fine lol 我知道这是一种新颖的方法,但是效果很好

You were close, I looked at your csv and since you have a header line I think it may good to use your S.No as a unique taskid: 您接近了,我查看了您的csv,由于您有标题行,所以我认为最好将S.No用作唯一的taskid:

import pandas as pd
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-o', '--option', metavar='', help='-o <option> write either you want to add or view')

# Here I added the action="append"
parser.add_argument('-l', '--select', metavar='', help='-l <used to select the task for modification', action="append")
args = parser.parse_args()


def modify(filename, taskids):
    taskids = list(map(int, taskids))  # just to change from str to int for your taskids
    df = pd.read_csv(filename, sep=";")
    df.loc[df["S.No"].isin(taskids), "Status"] = "complete"
    df.to_csv(filename, sep=";", index=False)

modify("csv.csv", args.select)

I'm using Pandas dataframe to make it easier. 我正在使用Pandas数据框来简化它。 The df.loc[...] line is for selecting each row where S.No is one of your task id given in the command line and changing the Status column to "complete". df.loc[...]行用于选择每一行,其中S.No是您在命令行中给定的任务ID之一,并将Status列更改为“ complete”。

Also I made a little change that I think you can be interested in: I just added a small action="append" in your parser for the select option. 另外,我做出了一些我认为您可能会感兴趣的更改:我刚刚在解析器中为select选项添加了一个小的action="append" This means you will be able to change multiple tasks at once by doing something like: 这意味着您可以通过执行以下操作来一次更改多个任务:

python todoarg.py -o modify -l 2 -l 6 -l 3

For your option parameter I can recommend you using the choices argument in the parser: 对于您的option参数,我建议您使用解析器中的choices参数:

parser.add_argument(
    "-o", "--option",
    type    = str,
    choices = [
        "modify",
        "add",
        "cook_a_turkey"
    ],
    default = "modify",  # you can even use a default choice if the parameter is not given
    metavar = "",
    help    = "some help"
)

And for how to select which method to use based on the value given to the option parameter I don't think I have a good way to do this but maybe something like this can work: 对于如何基于给option参数提供的值选择要使用的方法,我认为我没有很好的方法来执行此操作,但也许这样的方法可以工作:

my_methods = {
    "modify": modify,  # they keys are the same as provided in the choices in the argument parser
    "add": add_task,
    "cook_a_turkey": cook_that_turkey,
}
# And you can call the function like this: However you will have to change a bit your functions to parse the arguments in each of them.
my_methods[parser.option]("csv", args)

# For instance the modify will become:
def modify(filename, args):
    taskids = list(map(int, args.select))
    # ...
def add_task(filename, args):
    # do stuff
def cook_that_turkey(filename, args):
    # your grandma recipe

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM