具有重复的排序列表的有效排列

时间:2018-02-18 09:35:50

标签: python python-3.x list permutation repeat

我有一个分配给排名的名单,通常是排名重复。我想生成列表的所有排列,并按排序顺序保持排名。例如:

[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 个答案:

答案 0 :(得分:1)

以下是使用groupbypermutationsproduct的{​​{3}}解决方案。因为它主要使用生成器,所以它在内存上应该不会太重。如果您不需要将结果作为列表,但是例如只是想迭代它,那么内存需求实际上应该是相当适度的。

如果你需要列表,你需要列表的内存,但不多。

但是我担心你的数字,单独的最终列表将太大而不适合记忆。循环将永远。

>> 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)]