更新:解决方案
我设法让以下代码工作
import collections
from lxml import etree
## Up here is code for getting an .xml input file from the user, opening that file, etc. ##
## This part is in a for loop that goes over each order in the xml file ##
## This all would have an extra indent because it is under this: for order in root.xpath('//order'): ##
itemlist = []
## This part looks through the .xml file for the order it is currently iterating and puts the items into a list ##
for element in order.iter('items'):
itemlist.append ("%s" % str.upper((element.get('type'))))
## This part 'sanitizes' the order name from the .xml file for use as a key ##
for element in order.iter('order'):
ordername = element.get('name')
strippedordername = re.sub('[/\()!@#$%^&*()]', '', ordername)
allordernames.append (strippedordername)
print strippedordername
#print itemlist
## This bit compiles a shopping list of items in a special dict subclass called a Counter. ##
ordercounter.update(itemlist)
## This part makes a dict with order names for its keys and their corresponding Counter of items as its values ##
ordersdictsdict[strippedordername] = collections.Counter(itemlist)
zeros = dict((k,0) for k in ordercounter.keys())
for cntr in ordersdictsdict.values():
cntr.update(zeros)
#print ordercounter
#print ordersdictsdict
key_order = list(ordercounter.keys())
print key_order
with open(out_file,'w') as fout:
fout.write('Order,'+','.join(key_order)+'\n')
fout.write('Totals,'+','.join(str(ordercounter[k]) for k in key_order)+'\n')
for ordername,dct in ordersdictsdict.items():
fout.write(ordername+','+','.join(str(dct[k]) for k in key_order)+'\n')
fout.closed
输出最终看起来像这样:
Order,Spam,Eggs,Baked Beans,Sausage
Totals,13,1,1,1
Order for Joe,2,1,0,1
Order for Jill,11,0,1,0
我有的
我的脚本接受输入的 xml 文件并对其进行解析,查找订单名称,然后查找订单内容。一个xml文件中可以有多个订单。然后我有一个柜台,可以统计所有订单中的所有物品,并给我一个总的购物清单。
鉴于这两个样本订单:
Order for Joe: Spam, Egg, Sausage, Spam
Order for Jill: Spam, Spam, Spam, Spam, Spam, Spam, Spam, Beaked Beans, Spam, Spam, Spam, Spam
计数器看起来像这样:
Counter({'Spam': 13,'Baked Beans' 1, 'Egg': 1, 'Sausage': 1})
然后我将其写入 csv 文件,使其看起来像这样:
Item,Count
Spam,13
Baked Bean,1
Egg,1
Sausage,1
我想要的是
虽然总购物清单很好,但我想扩展我的输出 csv 文件,以包括每个订单名称的购物清单。我不在乎订单名称是行还是列。我也并不真正关心不在该顺序中的项目的单元格是 a0
还是空,但我将0
在我的示例中使用。
订单名称为行的示例所需输出
Order Name,Spam,Baked Beans,Egg,Sausage
Totals,13,1,1,1
Order for Joe,2,0,1,1
Order for Jill,11,1,0,0
以订单名称作为列的示例所需输出
Item,Totals,Order for Joe,Order for Jill
Spam,13,2,11
Baked Beans,1,0,1
Egg,1,1,0
Sausage,1,1,0
笔记
我希望这个脚本适用于任何输入文件——当然,如果输入只包含一个订单,那么Totals
将匹配该订单名称。我必须首先制作一个总计计数器(以便我拥有相关订单的所有可能项目),然后在 csv 中填写每个订单的计数。换句话说,我无法通过将项目写入硬编码来启动我的 csv 文件,因为下一个输入文件可能在订单中有不同的项目。