項目需求很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的源代碼,應該會對我的個人提升有很大幫助吧。