python组合求和

本文介绍了如何通过改进Python代码,结合itertools模块的combinations函数和openpyxl模块处理Excel数据,提升查找数组元素和为特定值的组合速度。通过实例展示了如何读取Excel中的数据,执行组合搜索,并将结果写回Excel。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

改进《python从数组中找出所有和为M的组合》,使用python排列组合itertools模块combinations函数,并使用openpyxl模块从Excel中读取数据、写入计算结果
python代码如下

import time
import os.path
from itertools import combinations
from openpyxl import load_workbook

def search(list_n, sum_m, m=0):
    """
    对列表中的n个元素,任取m个组合,使其和为需查找的值,输出结果以列表嵌套形式
    :param list list_n: 列表list_n,内有元素n个
    :param Number sum_m: 需查找的和值sum_m
    :param int m: 符合和值sum_m的组合内元素限定的个数m
    返回结果:列表内嵌套元组[(),()]
    注意:当 m>n 时返回空列表,m默认为0输出所有符合和值的组合
    """
    start_time = time.time()
    result = []  # 空列表,存放 “符合和值sum_m的所有组合” 
    if m < 0 or not isinstance(m, int):
        print('参数异常,m应为自然数')
        return []
    elif m > len(list_n):  # 当 m>n 时返回空列表
        print('参数异常,m>n')
        return []
    elif m == 0:  # m=0时返回所有的组合
        for i in range(1, len(list_n)+1):
            combin_list = list(combinations(list_n, i))  # 迭代器写入列表
            for c in combin_list:
                if sum_m == sum(c):
                    result.append(c)
        end_time = time.time()
        print('所有组合都已查找,用时:%.4f秒' % (end_time - start_time))
        return result
    else:  # 一般情况,只返回限定m的组合
        combin_list = list(combinations(list_n, m))  # 迭代器写入列表
        for c in combin_list:
            if sum_m == sum(c):
                result.append(c)
        end_time = time.time()
        print('所有组合都已查找,用时:%.4f秒' % (end_time - start_time))
        return result

def read_excel_search(excel, sheet='Sheet1'):
    """
    读取Excel表数据的待查找list_n、和sum_m、元素个数m,返回符合条件的值,写入该Excel表
    :param str excel: Excel表格,包含数据--待查找list_n、和sum_m、元素个数m
    :param str sheet: Excel表格哪个sheet,默认为'Sheet1'
    注意:list_n限定从A2单元格向下n个,sum_m限定B2单元格,m限定C2单元格,输出结果限定D2单元格向下
    注意:若list_n数据类型错误,则程序退出
    """
    start_time = time.time()
    ## openpyxl读取Excel
    workbook =  load_workbook(excel)  # openpyxl.load_workbook()打开文件
    worksheet = workbook[sheet]
    nrow = worksheet.max_row  # 最大行数,空行不影响
    list_n = []  # list_n
    sum_m = worksheet.cell(2, 2).value  # sum_m
    m = worksheet.cell(2, 3).value    # m
    for row in range(2, nrow+1):  # 从A2开始,openpyxl从1开始计数
        cell = worksheet.cell(row,1).value
        if isinstance(cell, int) or isinstance(cell, float):
            list_n.append(cell)
        else:
            # 退出并抛出自定义异常,cell.coordinate返回单元格的坐标
            raise Exception('{}数据类型异常,请输入数值,而不是{}'.format(worksheet.cell(row,1).coordinate, type(cell)))

    ## 调用查找函数,返回符合条件的值
    result = search(list_n, sum_m, m)

    ## openpyxl写入Excel
    write_row = 2
    for r in result:
        str_write = ''
        for i in r:
            str_write += '+' + str(i)
        worksheet.cell(write_row, 4).value = '=' + str_write[1:]  # 打开Excel显示为正常公式计算后的结果,便于查看
        write_row += 1
    new_file = '{}_已查找{}'.format(os.path.splitext(excel)[0], os.path.splitext(excel)[1])
    workbook.save(new_file)
    #workbook.save(excel)  # 也可保存为当前文件
    end_time = time.time()
    print('Excel已写入查找结果,累计用时:%.4f秒' % (end_time - start_time))

if __name__ == '__main__':
    xlsx = r'E:\测试\组合求和.xlsx'
    read_excel_search(xlsx)

运行结果:运行速度提高了5-6倍
python组合求和-举例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔_51

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值