0
from itertools import permutations
perms = permutations("hello",5)

This gives me a weird <> thing I don't understand. It seems to work to go

for i in perms:
    print(i)

But I don't want to run through all permutations as there are very many of them. So I want to be able to do something like

perms[index]

to give ("h","e","l","l","o"). But this breaks because it's "not subscriptable". So how do I get just ("h","e","l","l","o") from this? Thank you!

  • So are you looking to parse all permutations and indeed ignore *some* of them, or do you have only a very limited number of permutations to generate, in which case `itertools.permutations` is probably not the best way to go? – Corentin Pane Nov 07 '19 at 11:01
  • That weird `<>` thing is an iterator – Sayse Nov 07 '19 at 11:01
  • `perms = list(permutations("hello",5))` – Sayandip Dutta Nov 07 '19 at 11:01
  • 1
    Possible duplicate of [Fastest way to convert an iterator to a list](https://stackoverflow.com/questions/3790848/fastest-way-to-convert-an-iterator-to-a-list) – Sayse Nov 07 '19 at 11:02
  • 1
    Try to convert into a `list` by `list(perms)` – Saleem Ali Nov 07 '19 at 11:02
  • 2
    Possible duplicate of [Get the nth item of a generator in Python](https://stackoverflow.com/questions/2300756/get-the-nth-item-of-a-generator-in-python) – Miguel Nov 07 '19 at 11:02
  • @SayandipDutta the question is about not generating/parsing all permutations, so materializing the iterator as a list does not help I think. – Corentin Pane Nov 07 '19 at 11:02
  • 2
    I guess it's only an example, but just in case the OP really only wants to turn `"hello"` into `('h', 'e', 'l', 'l', 'o')`, they just need `tuple('hello')`... – David Buck Nov 07 '19 at 11:08
  • 1
    @CorentinPane Yeah, I guess I misunderstood. But I am not entirely sure what the OP wants even now. For example I can't understand how would he be able to know which index contains `("h","e","l","l","o")`. – Sayandip Dutta Nov 07 '19 at 11:11
  • you could try `itertools.islice(perms, index, index+1)` – furas Nov 07 '19 at 11:13
  • @furas same issue here, `islice` still goes through all previous permutations to find the one you need. – Corentin Pane Nov 07 '19 at 11:14
  • @CorentinPane yes, but it is better then using `list()`. if you want something better then you would have to write something similar to `permutations` from scratch – furas Nov 07 '19 at 11:16
  • Thank you all for the help but I now realise I have far too many permutations for this to be a feasible strategy. Going to rethink and try a different method. Thanks again though! – Charlie Lutra Nov 08 '19 at 17:56

1 Answers1

1

If you want to get the nth permutation of a sequence in lexicographic order without having to generate all of them, you can use this snippet adapted from here:

from functools import reduce

def Factorial (n):
    return reduce(lambda x, y: x * y, range(1, n + 1), 1)

def GetNthPermutation (seq, index):
    seqc = list(seq[:])
    result = []
    fact = Factorial(len(seq))
    index %= fact
    while seqc:
        fact = fact // len (seqc)
        choice, index = index // fact, index % fact
        result += [seqc.pop(choice)]
    return result

which you can use like this:

>>> print(GetNthPermutation(list("hello"), 3))
['h', 'e', 'l', 'o', 'l']
Corentin Pane
  • 4,794
  • 1
  • 12
  • 29