Python 无重复项的随机分区列表

Python 无重复项的随机分区列表,python,arrays,Python,Arrays,我有一个数组,它包含了一组数字n次中的每一次。带有n=2的示例: [0, 1, 2, 3, 4, 0, 1, 2, 3, 4] 我想要的是这个数组的一个分区,其中分区的成员 包含从数组中随机抽取的元素 不包含重复项 包含相同数量的元素(最多四舍五入)k k=4的输出示例: [[3,0,2,1], [0,1,4,2], [3,4]] [[3,0,2,2], [3,1,4,0], [1,4]] k=4的输出无效: [[3,0,2,1], [0,1,4,2], [3,4]] [[3,0,2

我有一个数组,它包含了一组数字
n
次中的每一次。带有
n=2的示例:

[0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
我想要的是这个数组的一个分区,其中分区的成员

  • 包含从数组中随机抽取的元素
  • 不包含重复项
  • 包含相同数量的元素(最多四舍五入)
    k
k=4的输出示例:

[[3,0,2,1], [0,1,4,2], [3,4]]
[[3,0,2,2], [3,1,4,0], [1,4]]
k=4的输出无效:

[[3,0,2,1], [0,1,4,2], [3,4]]
[[3,0,2,2], [3,1,4,0], [1,4]]
(这是一个分区,但分区的第一个元素包含重复项)

实现这一目标的最具Python风格的方式是什么?

和的组合可以使用:

from collections import Counter
import random

def random_partition(seq, k):
    cnts = Counter(seq)
    # as long as there are enough items to "sample" take a random sample
    while len(cnts) >= k:
        sample = random.sample(list(cnts), k)
        cnts -= Counter(sample)
        yield sample

    # Fewer different items than the sample size, just return the unique
    # items until the Counter is empty
    while cnts:
        sample = list(cnts)
        cnts -= Counter(sample)
        yield sample
这是一个生成器,
生成
s样本,因此您只需将其转换为一个
列表

>>> l = [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]

>>> list(random_partition(l, 4))
[[1, 0, 2, 4], [1, 0, 2, 3], [3, 4]]

>>> list(random_partition(l, 2))
[[1, 0], [3, 0], [1, 4], [2, 3], [4, 2]]

>>> list(random_partition(l, 6))
[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]

>>> list(random_partition(l, 4))
[[4, 1, 0, 3], [1, 3, 4, 0], [2], [2]]

最后一个案例表明,如果函数中的“随机”部分返回“错误”样本,则此方法可能会给出奇怪的结果。如果这种情况不应该发生,或者至少不经常发生,您需要弄清楚如何对样本进行加权(例如使用),以最小化这种可能性。

您的分区还没有很好地定义。如果k>L/n(其中L是元素的总数),您会怎么做。例如,在数组中,k=6时返回什么?可能将输入读入
计数器
,然后递减该
计数器
中的
k
随机项,跟踪哪些项(这些是输出中的子列表)。然后继续这样做,直到所有条目都用尽。我担心对于
n
k
的某些值,以及集合的大小,输出中的子列表数量可能是随机的。我不知道这是否会成为一个问题,但这是值得关注的