我想知道迭代分区给定大小的列表的最佳方法(在Python中)。
比如说,我们有列表[1,2,3,4,5]
,我们想要k=3
个分区。这样做的一个不好的方法是写:
lst = [1,2,3,4,5]
for i in range(1,len(lst)):
for j in range(i+1, len(lst)):
print lst[:i], lst[i:j], lst[j:]
这给出了
[1], [2], [3,4,5]
[1], [2,3], [4,5]
...
[1,2,3], [4], [5]
但是如果我后来想要迭代k=4
分区,那么我将不得不添加一个for循环嵌套级别,这在运行时无法完成。理想情况下,我想写一些类似的东西:
for part in partitions([1,2,3,4,5], k):
print part
有谁知道这样做的最佳方式?
答案 0 :(得分:2)
我通过写作完成了我想做的事情:
from itertools import tee, izip, combinations
def partitions(items, k):
N = len(items)
def pairwise(iterable): # Taken from itertools recipies
a, b = tee(iterable)
next(b, None)
return izip(a, b)
def applyPart(part, items):
lists = []
for l,h in pairwise([0] + part + [N]):
lists.append(items[l:h])
return lists
for part in combinations(range(1, N), k - 1):
yield applyPart(list(part), items)
答案 1 :(得分:1)
如果没有pairwise
,我会使用与您相同的想法:
from itertools import combinations
def partitions(items, k):
def split(indices):
i=0
for j in indices:
yield items[i:j]
i = j
yield items[i:]
for indices in combinations(range(1, len(items)), k-1):
yield list(split(indices))
答案 2 :(得分:0)
对于较大的列表,这可能有点低效,但它可以工作:
from itertools import product, islice
def partitions(seq, k):
for c in product(xrange(1, len(seq)+1), repeat=k):
if sum(c) == len(seq):
it = iter(seq)
yield [list(islice(it, x)) for x in c]
for part in partitions([1,2,3,4,5], 3):
print part
<强>输出:强>
[[1], [2], [3, 4, 5]]
[[1], [2, 3], [4, 5]]
[[1], [2, 3, 4], [5]]
[[1, 2], [3], [4, 5]]
[[1, 2], [3, 4], [5]]
[[1, 2, 3], [4], [5]]
对于更大的列表,您需要找到所有k
大小的range(1, len(sequence)+1)
子集,它们与序列的长度相加,然后根据它们对序列进行切片。