using the itertools
tool, I have all the possible permutations of a given list of numbers, but if the list is as follows:
List=[0,0,0,0,3,6,0,0,5,0,0]
itertools
does not "know" that iterating the zeros is wasted work, for example the following iterations will appear in the results:
List=[0,3,0,0,0,6,0,0,5,0,0]
List=[0,3,0,0,0,6,0,0,5,0,0]
they are the same but itertools
just takes the first zero ( for example ) and moves it at the fourth place in the list and vice-versa.
The question is: how can I iterate only some selected numbers and left alone others such like zero ? it can be with or without itertools
.
For example, there are 2! = 2*1 = 2 permutations of {1, 2}, namely {1, 2} and {2, 1}, and 3! = 3*2*1 = 6 permutations of {1, 2, 3}, namely {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2} and {3, 2, 1}.
Voilá - it works now - after getting the permutations on the "meat", I further get all possible combnations for the "0"s positions and yield one permutation for each possible set of "0 positions" for each permutation of the non-0s:
from itertools import permutations, combinations
def permut_with_pivot(sequence, pivot=0):
pivot_indexes = set()
seq_len = 0
def yield_non_pivots():
nonlocal seq_len
for i, item in enumerate(sequence):
if item != pivot:
yield item
else:
pivot_indexes.add(i)
seq_len = i + 1
def fill_pivots(permutation):
for pivot_positions in combinations(range(seq_len), len(pivot_indexes)):
sequence = iter(permutation)
yield tuple ((pivot if i in pivot_positions else next(sequence)) for i in range(seq_len))
for permutation in permutations(yield_non_pivots()):
for filled_permutation in fill_pivots(permutation):
yield filled_permutation
(I've used Python's 3 "nonlocal" keyword - if you are still on Python 2.7,
you will have to take another approach, like making seq_len
be a list with a single item you can then repplace on the inner function)
My second try (the working one is actually the 3rd)
This is a naive approach that just keeps a cache of the already "seen" permutations - it saves on the work done to each permutation but notonthe work to generate all possible permutations:
from itertools import permutations
def non_repeating_permutations(seq):
seen = set()
for permutation in permutations(seq):
hperm = hash(permutation)
if hperm in seen:
continue
seen.add(hperm)
yield permutation
Append each result to a List. Now you'll have every single possible combination and then do the following:
list(set(your_big_list))
Set will narrow down the list down to only the unique permutations. I'm not wholly sure if this is the problem you're trying to solve or you're worried about performance. Regardless just made an account so I thought I'd try to contribute something
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