对所有分区进行迭代器到k个组?

2024-10-02 00:26:18 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个listl,如何在K组的所有分区上得到迭代器?在

示例:L=[2,3,5,7,11,13],K=3

3组所有可能分区的列表:

[ [ 2 ], [ 3, 5], [ 7,11,13] ]
[ [ 2,3,5 ], [ 7, 11], [ 13] ]
[ [ 3, 11 ], [ 5, 7], [ 2, 13] ]
[ [ 3 ], [ 11 ], [ 5, 7, 2, 13] ]
etc...

==更新===

我正在研究一个解决方案,似乎是有效的,所以我只是复制粘贴它

^{pr2}$

输出:

for 5 elements, 2 configurations of group sizes
[(1, 1, 3), (1, 2, 2)]
group sizes (1, 1, 3)
((3,), (5,), (7, 11, 13))
((3,), (7,), (5, 11, 13))
((3,), (11,), (5, 7, 13))
((3,), (13,), (5, 7, 11))
((5,), (7,), (3, 11, 13))
((5,), (11,), (3, 7, 13))
((5,), (13,), (3, 7, 11))
((7,), (11,), (3, 5, 13))
((7,), (13,), (3, 5, 11))
((11,), (13,), (3, 5, 7))
===
group sizes (1, 2, 2)
((3,), (5, 7), (11, 13))
((3,), (5, 11), (7, 13))
((3,), (5, 13), (7, 11))
((5,), (3, 7), (11, 13))
((5,), (3, 11), (7, 13))
((5,), (3, 13), (7, 11))
((7,), (3, 5), (11, 13))
((7,), (3, 11), (5, 13))
((7,), (3, 13), (5, 11))
((11,), (3, 5), (7, 13))
((11,), (3, 7), (5, 13))
((11,), (3, 13), (5, 7))
((13,), (3, 5), (7, 11))
((13,), (3, 7), (5, 11))
((13,), (3, 11), (5, 7))
===

Tags: of示例列表forgroupetcelements解决方案
3条回答

这个问题的一个简单的替代视图是将三个集群标签中的一个分配给每个元素。在

import itertools
def neclusters(l, k):
    for labels in itertools.product(range(k), repeat=len(l)):
        partition = [[] for i in range(k)]
        for i, label in enumerate(labels):
            partition[label].append(l[i])
        yield partition

与@val的答案一样,可以对其进行包装以删除带有空集群的分区。在

Edited:正如@moose所指出的,下面只确定连续索引在同一个集群中的分区。对所有排列执行这种划分将给出所寻求的答案。在

Itertools对于这种组合列表非常有用。首先,我们将您的任务视为在数组中选择所有k-1个不同拆分点集的等效问题。这是由itertools.combinations来解决的,它返回组合而不替换给定iterable中的特定大小,它返回的值按照它们在原始iterable中找到的顺序排列。在

您的问题可以通过以下方法解决:

import itertools
def neclusters(l, K):
    for splits in itertools.combinations(range(len(l) - 1), K - 1):
        # splits need to be offset by 1, and padded
        splits = [0] + [s + 1 for s in splits] + [None]
        yield [l[s:e] for s, e in zip(splits, splits[1:])]

numpysplit函数的目的是使这类分区具有拆分偏移量,因此下面是一个生成numpy数组列表的替代方法:

^{pr2}$

这是可行的,尽管它可能是超级缺乏(我把它们全部分类以避免重复计算):

def clusters(l, K):
    if l:
        prev = None
        for t in clusters(l[1:], K):
            tup = sorted(t)
            if tup != prev:
                prev = tup
                for i in xrange(K):
                    yield tup[:i] + [[l[0]] + tup[i],] + tup[i+1:]
    else:
        yield [[] for _ in xrange(K)]

它还返回空的集群,因此您可能需要将其包装起来,以便只获取非空的集群:

^{pr2}$

只是为了检查一下:

def kamongn(n, k):
    res = 1
    for x in xrange(n-k, n):
        res *= x + 1
    for x in xrange(k):
        res /= x + 1
    return res

def Stirling(n, k):
    res = 0
    for j in xrange(k + 1):
        res += (-1)**(k-j) * kamongn(k, j) * j ** n
    for x in xrange(k):
        res /= x + 1
    return res

>>> sum(1 for _ in neclusters([2,3,5,7,11,13], K=3)) == Stirling(len([2,3,5,7,11,13]), k=3)
True

它起作用了!在

输出:

>>> clust = neclusters([2,3,5,7,11,13], K=3)
>>> [clust.next() for _ in xrange(5)]
[[[2, 3, 5, 7], [11], [13]], [[3, 5, 7], [2, 11], [13]], [[3, 5, 7], [11], [2, 13]], [[2, 3, 11], [5, 7], [13]], [[3, 11], [2, 5, 7], [13]]]

相关问题 更多 >

    热门问题