I accept Gareth Rice's answer as the most attractive explanation (with the exception of the answer from the Python library developers), namely that Python itertools.permutations does not compare element values. Think about it, about it and asks a question, but now I see how this can be seen as an advantage, depending on what itertools.permutations usually uses for.
Just for completeness, I compared the three methods of generating all the different permutations. Method 1, which is very inefficient in memory and in time, but requires the least new code, is to wrap Python's itertools.permutations , as in zeekay's answer. Method 2 is a generator-based C ++ version of next_permutation starting with this blog post . Method 3 is what I wrote, which is even closer to the C ++ next_permutation algorithm ; it changes the list in place (I did not make it too general).
def next_permutationS(l): n = len(l)
Here are some results. I have even greater respect for the Python built-in function: it is about three to four times faster than other methods when all the elements (or almost all) are different. Of course, when there are many repeating elements, using this is a terrible idea.
Some results ("us" means microseconds): l m_itertoolsp m_nextperm_b m_nextperm_s [1, 1, 2] 5.98 us 12.3 us 7.54 us [1, 2, 3, 4, 5, 6] 0.63 ms 2.69 ms 1.77 ms [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 6.93 s 13.68 s 8.75 s [1, 2, 3, 4, 6, 6, 6] 3.12 ms 3.34 ms 2.19 ms [1, 2, 2, 2, 2, 3, 3, 3, 3, 3] 2400 ms 5.87 ms 3.63 ms [1, 1, 1, 1, 1, 1, 1, 1, 1, 2] 2320000 us 89.9 us 51.5 us [1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4] 429000 ms 361 ms 228 ms
The code is here if anyone wants to research.