You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python循环出现MemoryError:装箱问题脚本优化求助

看起来你的代码逻辑本身是正确的(在示例数据下能得到预期输出),但出现MemoryError大概率是因为处理的数据集过大,或者有一些容易忽略的代码细节问题。我来帮你分析并给出解决方案:

首先,修正代码中的潜在问题

你用了max作为列表变量名,但max是Python的内置函数,虽然在这个小例子里不会直接报错,但这是非常不好的编程习惯,可能在后续扩展代码时引发奇怪的冲突。先把变量名改成remaining这类语义清晰的名字。

另外,用for-else结构虽然可行,但换成显式的标志变量会让代码可读性更强,不容易出错。修改后的基础代码如下:

B = 60
data = [35,21,40,12,24]
# 替换max为remaining,避免内置函数名冲突
remaining = [B]
sol = [[]]

for item in data:
    item_placed = False
    for idx, free_space in enumerate(remaining):
        if free_space >= item:
            # 将元素放入对应子列表,更新剩余容量
            remaining[idx] -= item
            sol[idx].append(item)
            item_placed = True
            break
    if not item_placed:
        # 没有合适的子列表,新建一个
        sol.append([item])
        remaining.append(B - item)

solved = len(sol)
print(solved)
print(sol)

这段代码运行后会输出你预期的结果:3 [[35, 21], [40, 12], [24]]

针对MemoryError的解决方案

如果你的实际data列表非常庞大(比如包含数百万甚至更多元素),不断向sol和remaining添加元素会占用大量内存,从而触发MemoryError。可以尝试以下优化:

  1. 改用首次适应递减算法(First Fit Decreasing)
    先将data按降序排序,再进行装箱,这种策略通常能生成更少的子列表(箱子),直接减少sol和remaining的长度,从而降低内存占用。示例代码:

    B = 60
    # 先降序排序数据
    data = sorted([35,21,40,12,24], reverse=True)
    remaining = [B]
    sol = [[]]
    
    for item in data:
        item_placed = False
        for idx, free_space in enumerate(remaining):
            if free_space >= item:
                remaining[idx] -= item
                sol[idx].append(item)
                item_placed = True
                break
        if not item_placed:
            sol.append([item])
            remaining.append(B - item)
    
    print(len(sol))
    print(sol)
    

    运行结果箱子数量和之前一致,但对于更大的数据集,能显著减少箱子总数。

  2. 使用更高效的数据结构存储剩余容量
    对于remaining列表,如果里面都是整数,可以用array.array来代替普通列表,它存储数据的内存效率更高(普通列表每个元素是一个对象引用,而array.array直接存储原始字节)。示例:

    import array
    
    B = 60
    data = [35,21,40,12,24]
    # 用array存储整数,类型代码'i'表示int
    remaining = array.array('i', [B])
    sol = [[]]
    
    for item in data:
        item_placed = False
        for idx in range(len(remaining)):
            free_space = remaining[idx]
            if free_space >= item:
                remaining[idx] -= item
                sol[idx].append(item)
                item_placed = True
                break
        if not item_placed:
            sol.append([item])
            remaining.append(B - item)
    
    print(len(sol))
    print(sol)
    
  3. 分块处理(仅在允许少量额外箱子的情况下)
    如果数据集大到无法一次性加载到内存,可以分块处理data,每处理完一块后,将剩余容量不足B的箱子合并(如果可能),但这种方法可能会导致最终的箱子数量略多于最优解,适合对箱子数量要求不是极端严格的场景。

内容的提问来源于stack exchange,提问作者Eloah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:08:44