代码之家  ›  专栏  ›  技术社区  ›  S. Avenci

带重复排序表的有效置换

  •  0
  • S. Avenci  · 技术社区  · 7 年前

    我有一个列有等级的名字的列表,通常等级是重复的。我想生成列表的所有排列,并保持列组的排序顺序。例如:

    [Sam(17), Harry(17), Bob(5), Sally(5)]
    

    将生成

    Sam(17), Harry(17), Bob(5), Sally(5)
    
    Sam(17), Harry(17), Sally(5), Bob(5)
    
    Harry(17), Sam(17), Bob(5), Sally(5)
    
    Harry(17), Sam(17), Sally(5), Bob(5)
    

    本质上,对于每个不同的等级组,都有n!组合。在这种情况下是2!*2.我很难找到一种有效的方法来对一个8个等级中有34个名字的列表进行排列。

    我的内存不足,正在尝试查找2!*2! * 4! * 2! * 2! *8! * 4! * 10! 不同的列表。

    是否有任何有效的方法生成此列表?python需要多少内存?

    1 回复  |  直到 7 年前
        1
  •  1
  •   jonrsharpe    7 年前

    这是一个 itertools 解决方案使用 groupby , permutations product . 由于它主要使用生成器,所以内存应该不会太大。如果您不需要将结果作为列表,但只想对其进行迭代,那么内存需求实际上应该相当适度。

    如果你需要这个列表,你需要内存来存储这个列表,但不需要太多。

    但我担心,仅凭你的数字,最终的名单就太大了,难以记忆。循环将永远持续。

    >> import itertools, operator
    >>> 
    >>> data = *zip('Peter Paul Mary Jack Jill'.split(), (17, 17, 17, 4, 4)),
    >>> data
    (('Peter', 17), ('Paul', 17), ('Mary', 17), ('Jack', 4), ('Jill', 4))
    >>> 
    # group by rank
    >>> groups = itertools.groupby(data, operator.itemgetter(1))
    # extract the groups and generate all permutations of each of them
    >>> permutations = map(itertools.permutations, map(operator.itemgetter(1), groups))
    # form the cartesian product of the permutations, flatten out excess nesting
    # convert inner generators to lists
    >>> result = map(list, map(itertools.chain.from_iterable, itertools.product(*permutations)))
    >>> for i in result:
    ...     print(i)
    ... 
    [('Peter', 17), ('Paul', 17), ('Mary', 17), ('Jack', 4), ('Jill', 4)]
    [('Peter', 17), ('Paul', 17), ('Mary', 17), ('Jill', 4), ('Jack', 4)]
    [('Peter', 17), ('Mary', 17), ('Paul', 17), ('Jack', 4), ('Jill', 4)]
    [('Peter', 17), ('Mary', 17), ('Paul', 17), ('Jill', 4), ('Jack', 4)]
    [('Paul', 17), ('Peter', 17), ('Mary', 17), ('Jack', 4), ('Jill', 4)]
    [('Paul', 17), ('Peter', 17), ('Mary', 17), ('Jill', 4), ('Jack', 4)]
    [('Paul', 17), ('Mary', 17), ('Peter', 17), ('Jack', 4), ('Jill', 4)]
    [('Paul', 17), ('Mary', 17), ('Peter', 17), ('Jill', 4), ('Jack', 4)]
    [('Mary', 17), ('Peter', 17), ('Paul', 17), ('Jack', 4), ('Jill', 4)]
    [('Mary', 17), ('Peter', 17), ('Paul', 17), ('Jill', 4), ('Jack', 4)]
    [('Mary', 17), ('Paul', 17), ('Peter', 17), ('Jack', 4), ('Jill', 4)]
    [('Mary', 17), ('Paul', 17), ('Peter', 17), ('Jill', 4), ('Jack', 4)]