对于给定的数据,我们常常对首次数据或末次数据感兴趣。比如销售明细数据,对商品第一次和最后一次卖出的时间、销量、金额等感兴趣。使用字典,可以提取首次数据和末次数据。[大谦Excel,dqexcel点com]
提取首次数据
在Python中,直接给字典指定新的键值对,可以往字典中添加元素。例如下面创建一个字典并逐个添加元素:
>>> dic={1:"a"} #创建字典
>>> dic[2]="b" #添加元素
>>> dic
{1: 'a', 2: 'b'}
>>> dic[3]="c" #添加元素
>>> dic
{1: 'a', 2: 'b', 3: 'c'}
对于已经按照时间先后进行排序的销售明细数据,采用这种逐个添加元素的方法创建的字典,第一次添加进去的就是该键对应的首次数据。添加后面的键值对时,如果发现该键已经存在,就跳过不添加,那么字典中最后剩下的,就是各键对应的首次数据。
对于图6-1中处理前的销售明细数据,提取各商品第一次卖出的数量。
1 import xlwings as xw
2 import os
3 root = os.getcwd() #获取当前工作目录
4 app = xw.App(visible=True, add_book=False)
5 wb=app.books.open(fullname=root+r"\销售流水-首次.xlsx",read_only=False)
6 sht=wb.sheets(1)
7 rows=sht.cells(1,"B").end("down").row #数据行数
8 arr=sht.range(sht.cells(1,2),sht.cells(rows,3)).value #数据返回到二维列表
9 dic={arr[0][0]:arr[0][1]} #创建字典
10 for i in range(rows): #遍历各行数据
11 if(arr[i][0] not in dic): #如果dic中没有,添加元素
12 dic[arr[i][0]]=arr[i][1]
13 sht.range(sht.cells(1,"F"),sht.cells(len(dic),"G")).options(dict).value=dic
第1行导入xlwings包。
第2-3行导入os包,用getcwd函数获取当前目录,即sam07-01.py所在的目录。
第4行用xlwings的App函数创建一个Excel应用窗口,可见,但不添加工作簿。
第5行用books对象的open方法打开当前目录下的“销售流水-首次.xlsx”文件。因为接下来要提取首次数据并且将最终结果添加到工作表中,所以打开的工作簿必须是可写的,即将read_only参数的值设置为False。
第6-8行获取第1个工作表,用range对象的end方法获取数据的行数,把第2列第3列构成的区域内的数据保存在二维列表arr中。
第9行创建字典dic,并用二维列表arr中的第1行数据进行初始化。第1行第1列的商品数据为键,第2列的销量数据为值,构成键值对。
第10-12行用一个for循环往字典dic中添加新的键值对,第11行为判断语句,如果添加时的键在字典中已经存在,则不添加或修改。循环结束时,字典中各键值对对应的就是各商品第1次卖出的数量。
图6-1 提取首次数据前后的工作表
第13行使用了xlwings包的选项功能将字典输出到指定位置。用range属性的参数指定输出区域的左上角单元格坐标和右下角单元格坐标,options属性的参数设置为dict,表示按字典写入到工作表指定区域。字典的键和值各放一列。关于xlwings包的选项功能,第4章有更详细的介绍,请参阅。
在Python IDLE文件脚本窗口,在"Run"菜单中单击"Run Module"选项,各商品首次数据的提取结果添加到工作表中,如图6-1中处理后工作表所示。
提取末次数据
在Python中,对于给定的字典,用键进行索引并赋值时,如果键在字典中不存在,新的键值对会作为新元素添加到字典中。但是,如果该键已经存在,进行赋值时会修改它的值。例如下面创建一个字典并修改已有键的值:
>>> dic={1:"a",2:"b",3:"c"}
>>> dic[3]="d" #如果键存在,覆盖值
>>> dic
{1: 'a', 2: 'b', 3: 'd'}
对于已经按照时间先后进行排序的销售明细数据,采用这种方法进行添加或修改后最后字典中的键值对,都是各键以及它们对应的末次数据。
对于图6-2中处理前的销售明细数据,提取各商品最后一次卖出的数量。
1 import xlwings as xw
2 import os
3 root = os.getcwd() #获取当前工作目录
4 app = xw.App(visible=True, add_book=False) #创建Excel应用
5 wb=app.books.open(fullname=root+r"\销售流水-末次.xlsx",read_only=False)
6 sht=wb.sheets(1)
7 rows=sht.cells(1,"B").end("down").row #数据行数
8 arr=sht.range(sht.cells(1,2),sht.cells(rows,3)).value #返回数据到二维列表
9 dic={arr[0][0]:arr[0][1]} #创建字典
10 for i in range(rows): #遍历行数据,对于相同的键,后值替换前值
11 dic[arr[i][0]]=arr[i][1]
12 sht.range(sht.cells(1,"F"),sht.cells(len(dic),"G")).options(dict).value=dic
第1-5行的说明同6.1.1小节的代码说明。
第6-8行获取第1个工作表,用range对象的end方法获取数据的行数,把第2列第3列构成的区域内的数据保存在二维列表arr中。
第9行创建字典dic,并用二维列表arr中的第1行数据进行初始化。第1行第1列的商品数据为键,第2列的销量数据为值,构成键值对。
第10-11行用一个for循环往字典dic中添加新的键值对,或者如果添加时的键在字典中已经存在,则用当前商品销量修改原销量值。循环结束时,字典中各键值对对应的就是各商品最后一次卖出的数量。
第13行使用了xlwings包的选项功能将字典输出到指定位置。用range属性的参数指定输出区域的左上角单元格坐标和右下角单元格坐标,options属性的参数设置为dict,表示按字典写入到工作表指定区域。字典的键和值各放一列。关于xlwings包的选项功能,第4章有更详细的介绍,请参阅。
在Python IDLE文件脚本窗口,在"Run"菜单中单击"Run Module"选项,各商品末次数据的提取结果添加到工作表中,如图6-2中处理后工作表所示。
图6-2 提取末次数据前后的工作表