我正在编写一个脚本来查看我的库存,将其与所有可能库存项目的主列表进行比较,并告诉我我缺少哪些项目。我的目标是一个 .csv 文件,其中第一列包含一个唯一的键整数,然后其余几列将具有与该键相关的数据。例如,我的最终目标 .csv 文件的三行片段可能如下所示:
100001,apple,fruit,medium,12,red
100002,carrot,vegetable,medium,10,orange
100005,radish,vegetable,small,10,red
这方面的数据来自几个来源。第一,对 API 服务器的查询为我提供了库存中物品的键列表。第二,我将 .csv 文件读入一个字典,该字典将所有可能键的键与项目名称相匹配。此 .csv 文件的前 5 行的片段可能如下所示:
100001,apple
100002,carrot
100003,pear
100004,banana
100005,radish
请注意,我的库存列表中的任何键将如何在这两个列 .csv 文件中找到,该文件提供所有键及其相应的项目名称,并且此列表减去我手头的库存会产生我正在寻找的东西(这是我需要的库存要得到)。
到目前为止,我可以获得一个 .csv 文件,其中仅包含我在库存中没有的项目的键和项目名称。给出手头的库存清单,如下所示:
100003,100004
我生成的 .csv 文件的片段如下所示:
100001,apple
100002,carrot
100005,radish
这意味着我的库存中有梨和香蕉(因此它们不在此 .csv 文件中。)
为了得到这个,我有一个函数可以在给定一个看起来像这样的项目 id 时获取项目名称:
def getNames(id_to_name, ids):
return [id_to_name[id] for id in ids]
然后是一个函数,它从我的库存服务器 API 调用中将键列表作为整数提供,该调用返回一个列表,我已经像这样运行这个函数:
invlist = ServerApiCallFunction(AppropriateInfo)
第三个函数将此 invlist 作为其输入,并返回我没有的项目的键(项目 ID)和名称的字典。它还将这个 dict 的信息写入 .csv 文件。我正在使用 set1 - set2 方法来执行此操作。它看起来像这样:
def InventoryNumbers(inventory):
with open(csvfile,'w') as c:
c.write('InvName' + ',InvID' + '\n')
missinginvnames = []
with open("KeyAndItemNameTwoColumns.csv","rb") as fp:
reader = csv.reader(fp, skipinitialspace=True)
fp.readline() # skip header
invidsandnames = {int(id): str.upper(name) for id, name in reader}
invids = set(invidsandnames.keys())
invnames = set(invidsandnames.values())
invonhandset = set(inventory)
missinginvidsset = invids - invonhandset
missinginvids = list(missinginvidsset)
missinginvnames = getNames(invidsandnames, missinginvids)
missinginvnameswithids = dict(zip(missinginvnames, missinginvids))
print missinginvnameswithids
with open(csvfile,'a') as c:
for invname, invid in missinginvnameswithids.iteritems():
c.write(invname + ',' + str(invid) + '\n')
return missinginvnameswithids
然后我这样称呼:
InventoryNumbers(invlist)
有了这个解释,现在开始我的问题。我想通过添加其他列来扩展此输出 .csv 文件中的数据。这方面的数据将从另一个 .csv 文件中提取,其中的一个片段如下所示:
100001,fruit,medium,12,red
100002,vegetable,medium,10,orange
100003,fruit,medium,14,green
100004,fruit,medium,12,yellow
100005,vegetable,small,10,red
请注意,这不包含项目名称(因此我必须从只有两列键和项目名称的不同 .csv 文件中提取它)但它确实使用相同的键。我正在寻找一种方法来引入这些额外信息,以便我的最终 .csv 文件不仅会告诉我我没有库存的物品的键(即物品 ID)和物品名称,而且还会有类型、大小、数字和颜色列。
我看过的一个选项是集合中的defaultdict片段,但我不确定这是否是完成我想做的事情的最佳方式。如果我确实使用了这种方法,我不确定我将如何调用它来达到我想要的结果。如果其他方法更容易,我当然也愿意尝试。
如何获取我在库存中没有的项目的键和相应项目名称的字典,并将这些额外信息添加到其中,以便我可以将其全部输出到 .csv 文件?
编辑:当我输入这个时,我突然想到,我可能会通过创建一个新的单个 .csv 文件来让事情变得更容易,该文件的日期格式为键、项目名称、类型、大小、数字、颜色(基本上只是复制在项目名称列中的 .csv 中已经包含每个键的其他信息。)这样我只需要从一个 .csv 文件而不是两个文件中绘制。但是,即使我这样做了,我将如何仅根据那些不在库存中的物品的键来制作我想要的 .csv 文件?
回答:我在这里发布了另一个关于如何实施我接受的解决方案的问题(因为它给了我一个值错误,因为我的 dict 值是字符串而不是开始的集合),我最终决定我想要一个列表而不是一个集合(以保留顺序。)我还最终将带有项目名称的列添加到包含所有其他数据的 .csv 文件中,这样我只需要从一个 .csv 文件中提取。也就是说,这部分代码现在看起来像这样:
MyDict = {}
infile = open('FileWithAllTheData.csv', 'r')
for line in infile.readlines():
spl_line = line.split(',')
if int(spl_line[0]) in missinginvids: #note that this is the list I was using as the keys for my dict which I was zipping together with a corresponding list of item names to make my dict before.
MyDict.setdefault(int(spl_line[0]), list()).append(spl_line[1:])
print MyDict