-1

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?

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 Answers2

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
  • Just updated my answer. Verify if that's what you are looking for – looaka Jun 21 '21 at 08:50
  • 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