我正在使用CSV文件中的某些值创建制表符分隔文件。 CSV文件包含上个月发出的所有订单,我需要正确格式化以便能够导入当前使用的会计软件。以下是CSV文件中的数据示例:
Customer Order Number Item Line Number Quantity Product Description
cust1 Order #1 1 40 desc1
cust1 Order #2 1 101 desc2
cust2 Order #3 1 3 desc3
cust2 Order #3 2 8 desc3
cust2 Order #3 3 8 desc3
cust1 Order #4 1 75 desc4
现在,对于Order Number
的每个系列,我需要创建一个TDV文件的一部分,如下所示:(忽略括号,这些只是为了显示值来自上面)
1 cust1 HA5ZV1 Desc1 Due Date ...
2 1 (Item #) 40 (Qty) ... ... ...
1 cust1 HA6A17 Desc2 Due Date ...
2 1 (Item #) 101 (Qty) ... ... ...
1 cust2 HA6AM1 Desc3 Due Date ...
2 1 (Item #) 3 (Qty) ... ... ...
2 2 (Item #) 8 (Qty) ... ... ...
2 3 (Item #) 8 (Qty) ... ... ...
希望这是有道理的。到目前为止我所做的是从原始的CSV文件中创建一个字典,但是对于如何遍历我的字典并写入标题(标有“1”的行)一次感到困惑,然后写入值(每次出现相同的Order Number
时(标有“2”的行)。到目前为止,这是我的代码:
data = csv.reader(open(import_dir))
fields = data.next()
new_file = export_dir+os.path.basename(import_dir)
tab_file = open(export_dir+os.path.basename(import_dir), 'a+')
for row in data:
items = zip(fields, row)
item = {}
for (name, value) in items:
item[name] = value.strip()
tab_file.write('1\t'+item['Customer']+'\t'+item['Order Number']+'\t'
+item['Product Description']+'\t'+item['Due Date']+'\n'+
'2\t'+item['Item Line Number']+'\t'+item['Quantity']+'\t'+
...
但是此代码将标题数据放在每个订单项之前,而不是仅将其放在每个订单的开头。如果每个客户只订购了一个商品,那就没问题,但由于某些订单有多个订单项,因此会破坏格式。如果有人能够指出我正确的方向,那将是伟大的。谢谢!
答案 0 :(得分:0)
您希望使用itertools.groupby()
tool按客户编号对输入行进行分组:
import csv
import os
from itertools import groupby
from operator import itemgetter
new_file = os.path.join(export_dir, os.path.basename(import_dir))
with open(import_dir) as import, open(new_file, 'ab') as tab_file:
data = csv.reader(import)
writer = csv.writer(tab_file, delimiter='\t')
fields = next(data)
for customer, rows in groupby(data, key=itemgetter(0)):
first_row = next(rows)
item = {f: v.strip() for f, v in zip(fields, first_row)}
writer.writerow([1, customer, item['Order Number'], item['Product Description'], item['Due Date'])
writer.writerow([2, item['Item Line Number'], item['Quantity'], ...])
for i, row in enumerate(rows, 3):
item = {f: v.strip() for f, v in zip(fields, row)}
writer.writerow([i, item['Item Line Number'], item['Quantity'], ...])
groupby()
返回key
函数的当前结果,以及具有该键值的所有行的可迭代结果。一旦下一行不再具有相同的密钥,就会启动一个新组。
我改变的其他事情:
with
自动关闭打开的文件,无论发生了什么。os.path.join()
构建路径csv.writer(..., delimiter='\t')
编写制表符分隔文件;它只是另一种CSV方言,真的。csv.DictReader()
做同样的事情;无需读取第一行中的字段。