I am using python 3 and I am trying to find a way to get all the permutations of a list while enforcing some constraints.
For instance, I have a list L=[1, 2, 3, 4, 5, 6, 7]
I want to find all permutations. However, My constraints are:
Of course, I can generate all permutations and ignore those which do not follow these constraints but this wouldn't be efficient I guess.
There are two ways of generating permutations in Python: Using recursion. Using itertools.
A permutation, also called an “arrangement number” or “order”, is a rearrangement of the elements of an ordered list S into a one-to-one correspondence with S itself. A string of length n has n! permutation. Examples: Input : str = 'ABC' Output : ABC ACB BAC BCA CAB CBA.
The function itertool.permutations() takes an iterator and 'r' (length of permutation needed) as input and assumes 'r' as default length of iterator if not mentioned and returns all possible permutations of length 'r' each. Syntax: Permutations(iterator, r)
This approach filters permutations using a simple filter.
import itertools
groups = [(1,2),(3,4,5),(6,7)]
groupdxs = [i for i, group in enumerate(groups) for j in range(len(group))]
old_combo = []
for dx_combo in itertools.permutations(groupdxs):
if dx_combo <= old_combo: # as simple filter
continue
old_combo = dx_combo
iters = [iter(group) for group in groups]
print [next(iters[i]) for i in dx_combo]
What we are doing here is finding permutations of a multiset. (In this case the multiset is groupdxs
.) Here's a paper that details an O(1) algorithm for this.
def partial_permutations(*groups):
groups = list(filter(None, groups)) # remove empties.
# Since we iterate over 'groups' twice, we need to
# make an explicit copy for 3.x for this approach to work.
if not groups:
yield []
return
for group in groups:
for pp in partial_permutations(*(
g[1:] if g == group else g
for g in groups
)):
yield [group[0]] + pp
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With