如何更新我的同一个 csv 文件并将其用于 python 中的匹配?

How to update my same csv file and use it for matching in python?

有 2 个 csv files.My 第一个任务是用指定关键字匹配两个文件的内容,并创建一个包含关键字内容并命名为 keyword.csv.It 的新文件,工作正常。 问题 part:I 想要一次又一次地使用 remaining.csv 来删除那些与关键字匹配的值。 程序没有抛出任何错误,但没有正确写入 csv 中的所有内容。

import csv

handle2 =''
each=''
row=''
cat_var=''
handle1=''
with open('ss.csv') as handle2:
    for each in handle2:
        strng_conv = ''.join(map(str,each.rstrip('\n')))
        print strng_conv
        file_name = strng_conv+'.csv'
        print file_name
        cat_file = open(file_name,'wb')
        cat_var = csv.writer(cat_file,delimiter=' ')
        with open('repaired.csv', 'r') as csvfile:
            handle1 = csv.reader(csvfile, delimiter=' ')
            for row in handle1:
                if each.rstrip() in row:
                    cat_var.writerow(row)
                    csvfile.close()

                else:
                    with open('repaired.csv','w') as csvfile:
                        handle1 = csv.writer(csvfile,delimiter=' ')
                        handle1.writerow(row)
                csvfile.close()


        cat_file.close()

csvfile.close()
handle2.close()

ss.csv 包含类似

的项目
yepme
reebok
adidas
baggit

repaired.csv 包含

Waybill Contents    Amount  COD Amount  Type
928049  123456  yepme bag   1109    0   Pre-paid
904096  15116916453 yepme polish    518 0   Pre-paid
922222  52255       puma   abc     522  cod

假设它是否与我想要的 yepme 内容相匹配 repaired.csv shpuld 只有一行有 puma 意思是比赛后的所有剩菜

要像这样创建的示例输出文件-这些文件包含所有匹配的数据

yepme.csv
reebok.csv
adidas.csv

Repaired.csv 最后应该包含那些在任何关键字中都不匹配的行 就像我没有把 puma 放在比赛中一样,所以只有剩下的条目应该是留在 repaired.csv

中的 puma

你的问题是你没有完全理解IO在这里是如何工作的;

当您执行 with X... 时,幕后实际发生的事情是 python 调用对象的 __enter__ 方法,然后当范围离开时(即缩进级别with 语句的),它调用同一对象的 __exit__ 对象。

以下两个片段是等价的*:

with open("file1", "r") as a:
  ...

tmp = open("file1", "r")
a = tmp.__enter__()

...

a.__exit__()

(* 也就是说,如果您忽略被丢弃的异常等等)

对于 File 对象,__exit__() 将通过关闭文件和诸如此类的东西来清理 - 即你不应该在 with open(...) as X:.[=21= 之后关闭文件]

你正在做的第二件事可能是不确定的,可能不会让你得到你想要的结果:

您正在遍历文件的内容,同时编辑同一个文件(或者至少您认为您这样做)。您正在以几种不同的方式阅读文件。

当您这样做时 for line in file_object 遍历文件,移动内部指针。

当您打开文件,然后使用一些特殊的 reader 读取它时,您正在创建一个新对象 - 它将独立于实际文件。混合使用所有这些不同的方法可能会给您带来不一致和混乱的结果,并且在您对它们的工作方式做出假设时进行调试会令人头疼。

只读入两个原始文件,然后将它们解析为 python 对象,而不是打开和关闭所有这些文件,可能会更容易、更清晰。如果你改变你的问题,我会更新这个,这样你想做什么就更清楚了。

尝试这样的事情:

keywords = []
with open("ss.csv", "r") as keywords_file:
  for line in keywords_file:
    keywords.append(line.strip())


outputs = {}
left_overs= []
with open("remaining.csv", "r") as remaining_file:
  for line in remaining_file:

    for keyword in keywords:
      if keyword in line:
        if keyword in outputs:
          outputs[keyword].append(line)
        else:
          outputs[keyword] = [line]
        break
    else:
      left_overs.append(line)

for keyword, output in outputs.items():
  with open(keyword + ".csv", "w") as output_file:
    for line in output:
      output_file.write(line)

with open("remaining.csv", "w") as remaining_file:
  for line in left_overs:
    remaining_file.write(line)

这是否符合您的目标?

我会采用不同的逻辑:-)

  1. 由于ss.csv只有品牌名称,将其作为列表加载到内存中
  2. 初始化一个输出列表(开头为空),代码中将包含 row 个对象。这些是在 ss.csv
  3. 中没有任何匹配的行
  4. 只要找到匹配项,就通过 "ab" 模式创建一个 csv 文件。

这是代码格式的逻辑:-)

with open('ss.csv') as fo:
    all_brands = fo.read().split("\n")

output_row = []
with open("repaired.csv", "rb") as fo:
    handle1 = csv.reader(fo, delimiter=' ')
    for row in handle1:
        row = filter(None, row)
        if not row:
            continue
        if row[2].strip() in all_brands:
            print row[2].strip()
            with open(row[2].strip() + ".csv", "ab") as tmp_write:
                tmp_handle = csv.writer(tmp_write, delimiter=' ')
                tmp_handle.writerow(row)
        else:
            output_row.append(row)

with open("repaired.csv", "wb") as fo:
    handle = csv.writer(fo, delimiter=' ')
    handle.writerows(output_row)

这为您指定的输入生成了三个文件。 ss.csv,未动。 repaired.csv

Waybill Contents Amount COD Amount Type
922222 52255 puma abc 522 cod

yepme.csv

928049 123456 yepme bag 1109 0 Pre-paid
904096 15116916453 yepme polish 518 0 Pre-paid