随机分组项目列表,但有些项目不能在同一组中

时间:2018-01-25 22:28:19

标签: python

我有一个名单列表,我想将其放入n个组中。我可以轻松地做到这一点。但是,我的问题是,无论如何,有些项目都无法组合在一起。有一个简单的解决方案吗?

我现在就是这样做的:

import random

name_list = ["Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7"]
n = 2

random.seed(4)
random.shuffle(name_list)

test = [name_list[i:i + n] for i in xrange(0, len(name_list), n)]

print(test)

因此,我会得到4组,随机洗牌,最后一组只有1组(没关系)。但是,我们要说Item1Item5不能最终结合在一起。我该怎么做?

1 个答案:

答案 0 :(得分:0)

这里我们为随机分发的项目获取组或“块”。

<强>鉴于

import random
import itertools as it

import more_itertools as mit


random.seed(4)
n = 2
name_list = ["Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7"]
blacklist = ["Item1", "Item5"]

<强>代码

def get_random_groups(lst, size=2, blacklist=None):
    """Return distributed items among `m` groups of lists."""
    if blacklist is None:
        blacklist = []

    # Compute number of chunks
    length = (len(lst))
    if length % 2 == 0:
        m = length//size
    else:
        m = (length+1)//size

    # Edge cases
    if len(blacklist) > m:
        raise ValueError("Black-list is too long.  Must be < number of chunks.")
    if not set(blacklist).issubset(set(lst)):
        raise ValueError("Black-list is not a subset of the main list.")

    # Resize list
    remnant_list = list(set(lst) - set(blacklist))
    random.shuffle(remnant_list)

    # Build chunks and distribute (blacklist first)
    chunks = [list(c) for c in mit.distribute(m, blacklist)]
    random.shuffle(chunks)

    for chunk in chunks[:]:
        while len(chunk) < size:
            try:
                chunk += [remnant_list.pop(-1)]
            except IndexError:
                return chunks

<强>演示

# Without blacklist
get_random_groups(name_list, size=n)
# Out: [['Item5', 'Item1'], ['Item3', 'Item6'], ['Item7', 'Item2'], ['Item4']]

# With blacklist
get_random_groups(name_list, size=n, blacklist=blacklist)
# [['Item2', 'Item6'], ['Item1', 'Item3'], ['Item5', 'Item7'], ['Item4']]

# Invalid blacklist
blacklist = "Item1 Item3 Item 5 Item6 Item7".split()  
get_random_groups(name_list, size=n, blacklist=blacklist)
# ValueError: Blacklist is too long.  Must be < number of chunks.

# Invalid blacklist
blacklist = "Item1 Item9".split()  
get_random_groups(name_list, size=n, blacklist=blacklist)
# ValueError("Black-list is not a subset of the main list.")

<强>详情

  • 根据偶数或奇数长度列表计算块数。
  • 测试边缘情况(可选)。
  • blacklist中的项目将首先在块之间分配。因此,必须从剩余元素列表(remnant_list)中删除这些项目。
  • more_itertools.distribute是第三方工具,可在m个数量的块中促进分块分发项目。您可以选择实施自己的算法来完成这两项任务。
  • 除非满足块的size,否则将随机补余项添加到混洗块中。这种双重洗牌确保物品随机放置。