I'm trying to get all permutations of a list. So [2, 2, 1]
would out put a generator with outputs (2, 2, 1), (2, 1, 2), (1, 2, 2)
. I have tried a few ways of doing this but none have worked. For example, itertools.product
does not work. For example, when I use itertools.product
, the output is (1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2), (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)
. itertools.product
somehow gets three 1's in some of the lists even though I only inputted one 1. Is there any way to achieve what I want completely in a generator without generating duplicates?
Asked
Active
Viewed 116 times
-1

Ben
- 11
- 1
-
You are looking for "permutations", not "combinations". – mkrieger1 Jun 21 '21 at 08:28
-
Does this answer your question? [How to generate all permutations of a list?](https://stackoverflow.com/questions/104420/how-to-generate-all-permutations-of-a-list) – mkrieger1 Jun 21 '21 at 08:29
-
permutations alone would generate some duplicates, but combined with set() it gives what OP wants. – Christian Sloper Jun 21 '21 at 08:29
-
Well then https://stackoverflow.com/questions/6284396/permutations-with-unique-values – mkrieger1 Jun 21 '21 at 08:33
-
I'm looking for something that does this without generating duplicates without the need for `set` so I can keep it in a generator – Ben Jun 21 '21 at 08:34
2 Answers
0
From what I can understand, you want to print the possible permutations that you can make with these numbers. If that's what you want then you can use permutations
Here is a code to illustrate it
from itertools import permutations
permutation = permutations([2, 2, 1],3)
output = []
for i in list(permutation):
if i not in output:
output.append(i)
print(output)

looaka
- 18
- 6
-
This creates duplicates, I want a way to do that without duplicates completely inside a generator (without using `set`, etc.) – Ben Jun 21 '21 at 08:39
-
-
This answer is impractical for big lists, since it saves all of the values in a list which is very slow, at some point it'll just refuse to run – Ben Jun 21 '21 at 09:06
0
You can use numpy.roll
to shift the 1
between the indices. Do it in a function that yields the results to create generator object
import numpy as np
def roll(lst):
for _ in range(len(lst)):
lst = np.roll(lst, -1)
yield tuple(lst)
lst = roll([2, 2, 1])
print(lst) # <generator object roll at 0x000001E1D915AAC0>
print(list(lst)) # [(2, 1, 2), (1, 2, 2), (2, 2, 1)]

Guy
- 46,488
- 10
- 44
- 88