我需要一个给出列表L和数字的算法N,返回一个N较小的列表列表,其中子列表是"平衡的".例子:
algo(range(1, 8), 3) -> [[1,2,3], [4,5], [6,7]]
algo(range(1, 6), 4) -> [[1,2], [3], [4], [5]]
algo(range(1, 12), 5) -> [[1,2,3], [4,5], [6,7], [8,9], [10, 11]]
Run Code Online (Sandbox Code Playgroud)
如您所见,算法应该"更喜欢"输出中的第一个列表.
我已经尝试了几个小时,但我无法找到一个很好的简洁算法.顺便说一句,这将在Python中实现,但它确实是我在此之后的算法.这不是家庭作业,这是一个网站,它将在三列(Django)的列表中显示内容.
我从freenode上的#python得到了最好的答案,如下:
def split_up(l, n):
q, r = divmod(len(l), n)
def division_point(i):
return i * q + min(i, r)
return [l[division_point(i):division_point(i+1)] for i in range(n)]
Run Code Online (Sandbox Code Playgroud)
不要问我为什么它有效.:)虽然我会给出最多票数的人给出正确答案.
这是我提出的代码,没有排序.如果输入没有排序,只需打一个lst.sort().
我认为这很好,使用迭代器并使用islice来切断下一个部分.
import itertools
def partlst(lst, n):
"""Partition @lst in @n balanced parts, in given order"""
parts, rest = divmod(len(lst), n)
lstiter = iter(lst)
for j in xrange(n):
plen = len(lst)/n + (1 if rest > 0 else 0)
rest -= 1
yield list(itertools.islice(lstiter, plen))
parts = list(partlst(range(1, 15), 5))
print len(parts)
print parts
Run Code Online (Sandbox Code Playgroud)