Python 根据总数在循环中分解列表

Python breaking down list in loop based on total

我有一个我认为需要解决的相当复杂的问题。对于列表中的每个项目,我必须得到一个总面积。当足够多的这些项目的面积满足总面积时,这些项目必须拆分成一个单独的列表。该过程将继续处理列表中的后续项目。

代码看起来像这样,但是还不能工作:

all_areas = [1,2,3,4,5,6,7,8,9]

def get_area(n):
  # in my actual code the function does more than just return n as it is.
  return n

for i in all_areas:
  total_area=0
  ids=[]
  while total_area < 20:
    area = get_area(i)
    total_area+=area
    ids.append(i)
  else:
    # pass along ids before resetting counters
    call_another_function(ids)
    total_area=0
    ids=[]

以 20 作为阈值并使用给定参数,我打算使用 [1,2,3,4,5,6] 调用一次 call_another_function,然后使用 [7] 调用另一次,8,9]。然后循环将结束。对此问题的一些帮助将不胜感激。

我也想知道这是否适合使用 yieldgenerators?这些似乎是 Python 的有用功能,我以前从未使用过。

生成器解决方案:

如果您想学习生成器,可以通过以下方式使用它们:

def area_up_to(it, n):
    total_area = 0
    ids = []
    for x in it:
        total_area += get_area(x)
        ids.append(x)
        if total_area >= n:
            yield ids
            total_area = 0
            ids = []
    if ids:
        yield ids

要使用它,请调用生成生成器的函数:

area_gen = area_up_to(all_areas, 20)

然后你可以迭代它或调用next(area_gen)得到下一组:

for x in area_gen:
    print(x)

输出:

[1, 2, 3, 4, 5, 6]
[7, 8, 9]

修复您的代码:

你有一些逻辑问题和一个疯狂的 while..else,但这有效:

total_area=0
ids=[]
for i in all_areas:
    area = get_area(i)
    total_area += area
    ids.append(i)
    if total_area > 20:
        # pass along ids before resetting counters
        print(ids)
        total_area=0
        ids=[]
if ids:
    print(ids)

这里是一个方法。我不确定我在这里看到使用生成器的价值,但它可能会有所帮助,具体取决于更广泛的实施:

all_areas = [1, 2, 3, 4, 5, 6, 7, 8, 9]
thr = 20
groups = []

while all_areas:
    total = 0
    cur = []
    while total < thr:
        if not all_areas:
            break
        x = all_areas.pop(0)
        total += x
        cur.append(x)
    groups.append(cur)

print(groups)

输出:

[[1, 2, 3, 4, 5, 6], [7, 8, 9]]