我已经尝试过寻找解决方案,但是我对精确术语的无知并没有帮助,希望问题的标题和下面的代码是足够的解释。
到目前为止,这是我的工作:
C = [1,1,1,1,2,3,1,1,1,2,1]
sub_C = []
chunked_C = []
counter = 0
for i in C:
counter += i
if counter <= 3:
sub_C.append(i)
else:
chunked_C.append(list(sub_C))
del sub_C[:]
counter = i
sub_C.append(i)
print chunked_C
我希望chunked_C产生: [[1,1,1],[1,2],[3],[1,1,1],[2,1]]
不确定我哪里出错了,也许有人可以提供帮助。
编辑:我已经纠正了拼写错误。
同时
稍微修改一下,我需要将列表中不完整的尾部分块,即值小于3但我的数字用完了。
e.g:
C = [1,1,1,1,2,3,1,1,1,2,1,1]
so chunked_C = [[1,1,1],[1,2],[3],[1,1,1],[2,1],[1]]
希望这是有道理的。
进一步修订:
如果C = [1,1,1,1,1,2,3,1,1,1,2,1]
chunked_C等于[[1,1,1],[1,1],[2],[3],[1,1,1],[2,1]]
所以我猜逻辑需要进一步修改。
答案 0 :(得分:6)
编辑:首先,正如Ashwini在评论中指出的更正,我们需要确保我们释放最后一个块,即使它没有达到目标。
也就是说,使用itertools.groupby()
:
import itertools
c = [1,1,1,1,2,3,1,1,1,2,1]
class group_by_sum:
def __init__(self, target):
self.target = 3
self.current = False
self.sum = 0
def __call__(self, item):
self.sum += item
if self.sum > self.target:
self.sum = item
self.current = not self.current
return self.current
def group(self, iterable):
return [tuple(items) for _, items in itertools.groupby(iterable, self)]
>>> group_by_sum(3).group(c)
[(1, 1, 1), (1, 2), (3,), (1, 1, 1), (2, 1)]
显然,最后的便利方法不一定重要,但它使用起来更简单。
旧答案:
这可以通过生成器很好地完成:
def chunk_to_sum(iterable, target):
chunk_sum = 0
chunk = []
for item in iterable:
chunk_sum += item
if chunk_sum > target:
yield chunk
chunk = [item]
chunk_sum = item
else:
chunk.append(item)
if chunk: yield chunk
>>> list(chunk_to_sum([1, 1, 1, 1, 2, 3, 1, 1, 1, 2, 1], 3))
[[1, 1, 1], [1, 2], [3], [1, 1, 1], [2, 1]]
答案 1 :(得分:1)
我认为“if counter&lt; 3:”这一行是你想要它的倒退逻辑。这是我写的更正版本:
def chunk(to_chunk, n):
"""
>>> chunk([1,1,1,1,2,3,1,1,1,2,1], 3)
[[1, 1, 1], [1, 2], [3], [1, 1, 1], [2, 1]]
"""
result, accum, total = [], [], 0
for i in to_chunk:
accum.append(i)
if total + i >= n:
result.append(accum)
accum, total = [], 0
else:
total += i
return result
答案 2 :(得分:1)
是的,我想你想用一台发电机。这只是对Lattyware版本的轻微清理。 (去投票)
def chunk_to_sum(items, target_value):
chunk = []
for item in items:
chunk.append(item)
if sum(chunk) >= target_value:
yield chunk
chunk = []
C = [1,1,1,1,2,3,1,1,1,2,1,1]
list(chunk_to_sum(C, 3))
输出[2]: [[1,1,1],[1,2],[3],[1,1,1],[2,1]]
答案 3 :(得分:0)
由于未知原因,程序会忽略列表中的最后一个整数,所以这里是一个固定版本,只是在列表中添加了一个整数,所以它忽略它并正确地关注其余的
C = [1,1,1,1,2,3,1,1,1,2,1,1]
sub_C = []
chunked_C = []
counter = 0
for i in C:
counter += i
if counter <= 3:
sub_C.append(i)
else:
chunked_C.append(list(sub_C))
del sub_C[:]
counter = i
sub_C.append(i)
print chunked_C
产生
[[1, 1, 1], [1, 2], [3], [1, 1, 1], [2, 1]]
答案 4 :(得分:0)
你可以在这里使用迭代器,这里不需要额外的列表:
def solve(lis, chunk_size):
it = iter(lis)
first = next(it)
chunked_C = [[first]]
counter = first
for i in it:
if counter + i < chunk_size:
chunked_C[-1].append(i)
counter += i
else:
chunked_C.append([i])
counter = i
return chunked_C
print solve([1,1,1,1,2,3,1,1,1,2,1], 4)
print solve([1,1,1,1,1,2,3,1,1,1,2,1], 4)
<强>输出:强>
[[1, 1, 1], [1, 2], [3], [1, 1, 1], [2, 1]]
[[1, 1, 1], [1, 1], [2], [3], [1, 1, 1], [2, 1]]
使用生成器功能:
def solve(lis, chunk_size):
chunk = []
counter = 0
for i in lis:
if counter + i < chunk_size:
chunk.append(i)
counter += i
else:
yield chunk
chunk = [i]
counter = i
if chunk: yield chunk
print list(solve([1,1,1,1,2,3,1,1,1,2,1], 4))
print list(solve([1,1,1,1,1,2,3,1,1,1,2,1], 4))
<强>输出:强>
[[1, 1, 1], [1, 2], [3], [1, 1, 1], [2, 1]]
[[1, 1, 1], [1, 1], [2], [3], [1, 1, 1], [2, 1]]
答案 5 :(得分:0)
试试这个:
def get_subsection_from_index(l, index):
subsection = []
while sum(subsection) < 3:
if index < len(l):
subsection.append(l[index])
else:
break
index += 1
return subsection, index
i = 0
chunked_C = []
while i < len(C):
subsection, i = get_subsection_from_index(C, i)
chunked_C.append(subsection)
答案 6 :(得分:0)
两个嵌套的while循环如何:
C = [1,1,1,1,2,3,1,1,1,2,1]
out=[]
while C:
temp=[C.pop(0)]
while C and sum(temp) <3:
temp.append(C.pop(0))
out.append(temp)
print out
# [[1, 1, 1], [1, 2], [3], [1, 1, 1], [2, 1]]
如果效果很重要,请使用deque代替列表:
from collections import deque
C = [1,1,1,1,2,3,1,1,1,2,1]
Cd=deque(C)
out=[]
while Cd:
temp=[Cd.popleft()]
while Cd and sum(temp) <3:
temp.append(Cd.popleft())
out.append(temp)
或者,使用类似的逻辑并转换为生成器:
def gen_chunks(it,n):
try:
while it:
ck=[]
while sum(ck)<n:
ck.append(next(it))
yield ck
except StopIteration:
pass
print list(gen_chunks(iter(C),3))
# [[1, 1, 1], [1, 2], [3], [1, 1, 1], [2, 1]]
如果你想使用不加n
的'面包屑',那么很容易添加:
def gen_chunks(it,n, return_crumbs=False):
ck=[]
try:
while it:
if sum(ck)>=n:
yield ck
ck=[]
else:
ck.append(next(it))
except StopIteration:
if return_crumbs and ck:
yield ck
print list(gen_chunks(iter(C),3))
print list(gen_chunks(iter(C),3,True))
# [[1, 1, 1], [1, 2], [3], [1, 1, 1], [2, 1]] no crumbs
# [[1, 1, 1], [1, 2], [3], [1, 1, 1], [2, 1], [1]] with crumbs
# ^^^ crumb