python – 无论顺序如何,都生成重复列表

前端之家收集整理的这篇文章主要介绍了python – 无论顺序如何,都生成重复列表前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我想生成将列表中的索引与“插槽”相关联的组合.例如,(0,1)表示0和1属于同一时隙,而2属于另一个时隙. (0,1,1)表示1,2,3属于同一时隙,而0本身属于同一时隙.在此示例中,0和1只是识别这些插槽的方法,但不包含我的使用信息.

因此,对于我的目的,0)与(1,1)绝对相同,并且(0,1)等同于(1,0).

经典的笛卡尔积产生了许多我想要摆脱的重复.

这是我通过itertools.product获得的:

>>> LEN,SIZE = (3,1)
>>> list(itertools.product(range(SIZE+1),repeat=LEN))
>>>
[(0,0),1),(1,1)]

这就是我想得到的:

>>> [(0,1)]

使用小型列表很容易,但我不太明白如何使用更大的集合来完成此操作.你有什么建议吗?

如果不清楚,请告诉我,以便我澄清我的问题.谢谢!

编辑:基于Sneftel的答案,这个功能似乎有效,但我不知道它是否真的产生了所有结果:

def test():
    for p in product(range(2),repeat=3):
        j=-1
        good = True
        for k in p:
            if k> j and (k-j) > 1:
                good = False
            elif k >j:
                j = k
        if good:
            yield p
最佳答案
我首先提出以下意见:

>每个组合的第一个元素必须为0.
>第二个元素必须是0或1.
>第三个元素必须是0,1或2,但如果第二个元素为1则只能为2.

这些观察结果表明以下算法:

def assignments(n,m,used=0):
    """Generate assignments of `n` items to `m` indistinguishable
    buckets,where `used` buckets have been used so far.

        >>> list(assignments(3,1))
        [(0,0)]
        >>> list(assignments(3,2))
        [(0,1)]
        >>> list(assignments(3,3))
        [(0,2)]

    """
    if n == 0:
        yield ()
        return
    aa = list(assignments(n - 1,used))
    for first in range(used):
        for a in aa:
            yield (first,) + a
    if used < m:
        for a in assignments(n - 1,used + 1):
            yield (used,) + a

这将在几秒钟内处理您的用例(12项,5个桶):

>>> from timeit import timeit
>>> timeit(lambda:list(assignments(12,5)),number=1)
4.513746023178101
>>> sum(1 for _ in assignments(12,5))
2079475

这比你在答案结束时给出的函数(调用产品然后删除无效赋值的函数)快得多,如果它被修改为处理(12,5)用例:

>>> timeit(lambda:list(test(12,number=1)
540.693009853363

猜你在找的Python相关文章