Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 尽可能将整数列表分成与最大和有关的块_Python_Python 3.x - Fatal编程技术网

Python 尽可能将整数列表分成与最大和有关的块

Python 尽可能将整数列表分成与最大和有关的块,python,python-3.x,Python,Python 3.x,假设这是我的清单: [5, 3, 13, 8, 1, 2, 6, 4, 10, 1, 12, 3, 7, 1, 4] 如果可能的话,我想把它分成最多12个部分,这样结果应该是这样的: [[5, 3], [13], [8, 1, 2], [6, 4], [10, 1], [12], [3, 7, 1], [4]] 注意,代码不应该删除任何大于最大和的整数(在我们的例子中是13),而是将其隔离在子列表中 我使用以下代码成功地做到了这一点: lst = [5, 3, 13, 8, 1, 2, 6,

假设这是我的清单:

[5, 3, 13, 8, 1, 2, 6, 4, 10, 1, 12, 3, 7, 1, 4]
如果可能的话,我想把它分成最多12个部分,这样结果应该是这样的:

[[5, 3], [13], [8, 1, 2], [6, 4], [10, 1], [12], [3, 7, 1], [4]]
注意,代码不应该删除任何大于最大和的整数(在我们的例子中是
13
),而是将其隔离在子列表中

我使用以下代码成功地做到了这一点:

lst = [5, 3, 13, 8, 1, 2, 6, 4, 10, 1, 12, 3, 7, 1, 4]

start = 0
stop = 1
max_chunk_sum = 12
lst_count = len(lst)
result = []

while not stop > lst_count:
    chunk = lst[start:stop]
    chunk_sum = sum(chunk)
    chunk_count = len(chunk)

    if chunk_sum < max_chunk_sum:
        if stop != lst_count:
            stop += 1
        else:
            result.append(lst[start:stop])
            break
    else:
        if chunk_count == 1:
            result.append(lst[start:stop])
            start = stop
            stop += 1
        else:
            stop -= 1
            result.append(lst[start:stop])
            start = stop
            stop += 1

print(result)

但是我觉得对于这个问题有一个更聪明的解决方案(可能是使用列表理解?)

在这里,我迭代
lst
,我使用一个子列表
,我检查这个块是否大于12,否则我在
中附加新元素
I
。如果大于12,那么我将
附加到
结果
,并创建一个新块

lst = [5, 3, 13, 8, 1, 2, 6, 4, 10, 1, 12, 3, 7, 1, 4]

max_chunk_sum = 12
result = []
chunk = []
for i in lst:
    if sum(chunk) + i <= max_chunk_sum:
        chunk.append(i)
    else:
        if chunk:
            result.append(chunk)
        chunk = [i]
result.append(chunk)
print(result)

您可以使用列表理解,但您可以只检查将下一个元素添加到前一个列表中的总和是否会超过最大值,如果超过最大值,则添加一个新列表

result = [[lst.pop(0)]]

for item in lst:
    if sum(result[-1]) + item > max_chunk_sum:
        result.append([item])
    else:
        result[-1].append(item)

这是一个典型的工作减少

from functools import reduce
lst = [5, 3, 13, 8, 1, 2, 6, 4, 10, 1, 12, 3, 7, 1, 4]
init = lst[0:1]
rest = lst[1:]
max_sum = 12
reduce(lambda acc, cur: [*acc[0:-1], [*acc[-1], cur]]
                        if sum(acc[-1]) + cur <= max_sum else
                        [*acc, [cur]],
       rest,
       [init])
从functools导入reduce
lst=[5,3,13,8,1,2,6,4,10,1,12,3,7,1,4]
init=lst[0:1]
rest=lst[1:]
最大和=12
减少(lambda acc,cur:[*acc[0:-1],*acc[-1],cur]]

如果sum(acc[-1])+cur类似于@phoenixo,但我们可以使用生成器:

def cluster(iterable, max_int):
    start, *iterable = iterable
    cluster = [start]
    for value in iterable:
        if sum(cluster) + value <= max_int:
            cluster.append(value)
        else:
            yield cluster
            cluster = [value]
    yield cluster

您可以使用“累积”计算块溢出时带中断的运行总和。然后使用这些总和确定要包含在每个组中的索引范围:

a      = [5, 3, 13, 8, 1, 2, 6, 4, 10, 1, 12, 3, 7, 1, 4]
chunk  = 12

from itertools import accumulate
sums   = accumulate(a,lambda s,v: [s+v,v][s+v>chunk])
breaks = [ i+1 for (i,s),v in zip(enumerate(sums),a[1:]) if s+v>chunk]
groups = [ a[s:e] for s,e in zip([0]+breaks,breaks+[len(a)]) ]

print(groups)
# [[5, 3], [13], [8, 1, 2], [6, 4], [10, 1], [12], [3, 7, 1], [4]]
如果您正在寻找一个不使用库的解决方案,这里有一个简单的循环,它不需要使用sum,也不需要多次添加值:

array  = [5, 3, 13, 8, 1, 2, 6, 4, 10, 1, 12, 3, 7, 1, 4]
chunk  = 12

group,total = [],0
groups      = [group]
for value in array:
    total += value
    if total > chunk:
        group,total = [],value
        groups.append(group)
    group.append(value)

print(groups)

# [[5, 3], [13], [8, 1, 2], [6, 4], [10, 1], [12], [3, 7, 1], [4]]

如何定义智能、较短的代码?请尝试使用
lst=[14,5,3,13]
输出是
[[],[14],[5,3],[13]
,谢谢您的评论,我现在更新:)没问题。另一种解决方法是在开始时初始化
chunk=[lst[0]]
,然后在
lst[1:][/code>上循环。这将不需要更改循环体并保持其干净:)嘿,@godot,它不适用于
lst=[14,5,3,13]
@xilopaint,你是对的,初始化不正确。我纠正了,还是不正确,伙计。它返回列表的
[14],[5,3]]
,而不是
[14],[5,3],[13]
。你说得对,我走得太快了(我将永远被[x:-1]没有得到最后一个元素的事实所迷惑。。。
In [204]: list(cluster(ints, 12))
Out[204]: [[5, 3], [13], [8, 1, 2], [6, 4], [10, 1], [12], [3, 7, 1], [4]]
a      = [5, 3, 13, 8, 1, 2, 6, 4, 10, 1, 12, 3, 7, 1, 4]
chunk  = 12

from itertools import accumulate
sums   = accumulate(a,lambda s,v: [s+v,v][s+v>chunk])
breaks = [ i+1 for (i,s),v in zip(enumerate(sums),a[1:]) if s+v>chunk]
groups = [ a[s:e] for s,e in zip([0]+breaks,breaks+[len(a)]) ]

print(groups)
# [[5, 3], [13], [8, 1, 2], [6, 4], [10, 1], [12], [3, 7, 1], [4]]
array  = [5, 3, 13, 8, 1, 2, 6, 4, 10, 1, 12, 3, 7, 1, 4]
chunk  = 12

group,total = [],0
groups      = [group]
for value in array:
    total += value
    if total > chunk:
        group,total = [],value
        groups.append(group)
    group.append(value)

print(groups)

# [[5, 3], [13], [8, 1, 2], [6, 4], [10, 1], [12], [3, 7, 1], [4]]