将特定值写回.csv、Python

将特定值写回.csv、Python,python,csv,dictionary,Python,Csv,Dictionary,我有一个.csv文件,其中包含一些我想更改的数据。 看起来是这样的: 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 我的代码运行了我需要的大部分内容,但我不确定如何在.csv上写回以生成此结果 item_name,item_cost,item_priority,item_required,item_comple

我有一个.csv文件,其中包含一些我想更改的数据。 看起来是这样的:

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
我的代码运行了我需要的大部分内容,但我不确定如何在
.csv
上写回以生成此结果

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
我的代码:

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())

这里有几个问题

  • 您使用的是
    DictReader
    ,它读取数据很好,但读写数据不如原始文件好,因为字典不能确保列顺序(除非您不在意,但大多数情况下人们不希望交换列)。我只是阅读标题,找到列标题的索引,并在代码的其余部分使用该索引(no dicts=更快)
  • 写入时,将附加到csv。您必须删除旧内容,而不是附加内容。使用
    newline=''
    或者你会得到很多空行(python3)或者
    “wb”
    (python2)
  • 读取时,需要存储所有值,而不仅仅是要更改的值,否则将无法写回所有数据(因为您正在替换原始文件)
  • 当您修改时,您会对我刚才在给定索引处用一个简单的replace-in列表替换的内容进行过度复杂化(毕竟您希望在给定行将
    r
    更改为
    x
这是考虑到上述所有备注的固定代码

编辑:在之后添加您请求的功能:在
x
之后添加
c
,如果尚未添加,则根据需要扩展行

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)

我想这应该可以做到:

  • 打开一个可以读写的文件以进行更新(使用“+r”进行更新)
  • 不要再次打开它,而是使用csvfilewriter(我们在开始时创建)在那里编写它
  • 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)
    
    如果您不想更新csv,但想编写一个新的csv,下面是代码:

    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)
    

    使用熊猫:

    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)
    
    标记为_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
    

    请注意,根据说明,您应该保留尾随的逗号。

    谢谢您的帮助,它可以完美地工作!我现在正试图添加一个额外的功能。我需要在“x”更改后添加“c”。是否可以使用您提供的代码添加?示例输出:item_1,21,1,x,ci已经尝试过了,但是我得到了:line[idx_r+1]='c'索引器:列表分配索引超出范围您测试过这段代码吗?你打开同一个文件两次。是的,我是故意这样做的,因为我想更新它,你可以使用“始终选择”打开一个新文件,然后也这样做。在windows上不起作用。不会崩溃(令人惊讶!),但文件未更新。使用新文件时,它也无法正常工作。请尝试新代码,新代码将生成一个名为“items_new.csv”的新文件。让我知道这是否适用于windows系统应该适用是的。但是代码太复杂了:头已经在输入文件中了,为什么要硬编码呢?这部分很荒谬:
    对于键,新列表中的值。items():if value==“r”:新列表['item\u required']=“x”
    。如果new_list['item_required']=“r”:…不需要遍历字典值!!。最后:由于字典的原因,新文件的顺序与原始文件的顺序不同。