openpyxl + itertools 匹配到账的金额

项目需求很easy,有一天,一个项目上的同事告诉我,他来了很多款项,但是这些款项被公司财务支出的时候合并支出了。以至于他无法找到支出的项目是哪些项目。
因为项目实在太多,人工进行排列组合工作量实在是太巨大了,因此,我就想通过编程来解决这个问题。

项目需求

  • 项目需求:在表格1中有很多的金额列表,表格2中也有很多的金额列表
  • 表格1中的每个金额都是表格2中的2个或以上的金额组合而成
  • 求解对应关系

素材

  • 两个表格
  • 一个python程序
  • openpyxl模块及itertools模块

实现过程

openpyxl的使用

openpyxl是python的一个模块,用来操作excel表格,非常的方便,可以用来进行数据处理。

import itertools
from openpyxl import load_workbook
#打开excel
excel1 = load_workbook("核对收入.xlsx")
#获取sheet名称并切换
sheet = excel1.get_sheet_names()[1]
sheet = excel1.active
#构建数据字典并存储
data1 = dict()
for i in sheet['C']:
    if type(i.value) == type(3.14):
        data1['C' + str(i.row)] = i.value
excel1.close()
print(data1)
excel2 = load_workbook("开票信息台账表.xlsx")
sheet = excel2.get_sheet_names()[0]
sheet = excel2.active
data2 = dict()
for i in sheet['P']:
    if type(i.value) == type(3.14):
        data2['P' + str(i.row)] = i.value
excel2.close()
print(data2)

通过以上代码,已经成功把两个excel表格数据导入到内存中。数据量不大,全部在内存中进行计算也没有问题。如果数据量大,慎用这个方法,就要采取高级手段了。

itertools的使用

我只用其中的combinations(),返回不同的组合

L = [1, 2, 3, 4]
for i in itertools.combinations(L, 2):
    print(i)

输出结果如下

(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)

很明了了,这个题已经解开了。
遍历就完事儿了

for x in range(2, len(data2)):
    L = itertools.combinations(data2, x)
    for numbers in data1:
        for i in L:
            key = 0
            for j in i:
                key += j[1]
                if abs(data1[numbers] - key) < 0.01:
                    print(numbers, data1[numbers], i, key, sep=' ')

后续的思考

我是个菜鸡,只会无脑遍历。
今天一直在想如果不用itertools模块,我该怎样实现组合数。后来我有了个雏形,但是没有付诸实践:
从m个数里条n个数的组合,就相当于先确定一个数,再确定出另外n-1个数的组合,这个情形重复m次。
一直推到求2个数的组合,那就是先确定一个数,再挑选另一个数。

这个其实就是一个典型的递归思想了,但是不知道为什么,让我去实现它,我百思不得其解,而且最近确实还比较忙。
有空了读一下itertools模块中combinations的源代码,应该会对我的个人提升有很大帮助吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章