1

I am new to Python and am trying out itertools:

import itertools as it
obj = it.permutations(range(4))
print(obj)
for perm in obj:
    print( perm )

My Question: How do I view/print all the permutations in obj directly without using a for loop?

What I Tried: I tried using __dict__ and vars as suggested in this SO link but both do not work (former does not seem to exist for the object while latter generated 'TypeError: 'itertools.permutations' object is not callable').

Please pardon if my question is rather noobish - this attributes issue appears complicated and most of what is written in SO link flew over my head.

NoviceProg
  • 815
  • 1
  • 10
  • 22
  • 4
    you cast it to list; `list(it.permutations(range(4)))` – Ma0 May 11 '18 at 09:48
  • BUT, why do you need `itertools` ? – Frank AK May 11 '18 at 09:51
  • Thanks @Ev.Kounis! I've been trying so many different things in vain for the last few hours! Would you like to post it as a solution so that I can accept it? – NoviceProg May 11 '18 at 09:53
  • @FrankAK The lecturer in my course just used it as part of his solution to a different problem and I was just poking around out of curiousity... – NoviceProg May 11 '18 at 09:56
  • 1
    Many things in 3.6 return generators (map, zip, itertools.*) - they all need to be iterated to be consumed. If you stuff them inside a `list(gener)` it will internally iterate all of them and return a list containting each result in it. you can also stuff / evaluate them in list/set/dict comprehensions wich will also iterate over the generator-results. – Patrick Artner May 11 '18 at 09:56
  • Hi @PatrickArtner, is there a rule-of-thumb to know what is returned by various built-in methods? I read the help() for `permutations` - nowhere does it say a `generator` is returned. Hope you don't mind enlightening further... – NoviceProg May 11 '18 at 10:11
  • 1
    https://docs.python.org/3.4/library/itertools.html#itertool-functions : First sentence: `The following module functions all construct and return iterators.` - there is a difference between "iterables" "sequences" and "generators"(which I think of as returning a finite length iterable by means of giving you an iterator) that I happen to grapple with. Good post: [what-exactly-are-iterator-iterable-and-iteration](https://stackoverflow.com/questions/9884132/what-exactly-are-iterator-iterable-and-iteration). – Patrick Artner May 11 '18 at 10:36
  • @PatrickArtner: will read up on those concepts. And thanks to everyone who helped! – NoviceProg May 11 '18 at 10:39

1 Answers1

5

Just cast your obj to a list:

print(list(obj))

This will give you the following output:

[(0, 1, 2, 3), (0, 1, 3, 2), (0, 2, 1, 3), (0, 2, 3, 1), (0, 3, 1, 2), (0, 3, 2, 1), (1, 0, 2, 3), (1, 0, 3, 2), (1, 2, 0, 3), (1, 2, 3, 0), (1, 3, 0, 2), (1, 3, 2, 0), (2, 0, 1, 3), (2, 0, 3, 1), (2, 1, 0, 3), (2, 1, 3, 0), (2, 3, 0, 1), (2, 3, 1, 0), (3, 0, 1, 2), (3, 0, 2, 1), (3, 1, 0, 2), (3, 1, 2, 0), (3, 2, 0, 1), (3, 2, 1, 0)]

That's the direct answer to your question. Another good thing to figure out is whether you really need what you are asking for.

You see, there is a reason why permutations returns a generator. If you ain't familiar with that pattern, I'd strongly suggest reading about it. To make a long story short, generally you don't wanna cast such things to a list unless you really need it to be a list (e.g. you want to access items directly by index). In your case where you only need to print permutations there is absolutely nothing wrong with using for loop.

Here is one-liner to print one permutation per line:

print('\n'.join(str(permutation) for permutation in obj))

But again, simple for loop which you are using already is just fine. Remember that simple is better than complex.

Ernest
  • 2,799
  • 12
  • 28