[Python-ideas] Fwd: Extremely weird itertools.permutations

MRAB python at mrabarnett.plus.com
Fri Oct 11 23:38:41 CEST 2013


On 11/10/2013 21:27, David Mertz wrote:
> Andrew & Neil (or whoever):
>
> Is this *really* what you want:
>
>  >>> from itertools import permutations
>  >>> def nonredundant_permutations(seq):
> ...     return list(set(permutations(seq)))
> ...
>  >>> pprint(list(permutations([F(3,1), D(3.0), 3.0])))
> [(Fraction(3, 1), Decimal('3'), 3.0),
>   (Fraction(3, 1), 3.0, Decimal('3')),
>   (Decimal('3'), Fraction(3, 1), 3.0),
>   (Decimal('3'), 3.0, Fraction(3, 1)),
>   (3.0, Fraction(3, 1), Decimal('3')),
>   (3.0, Decimal('3'), Fraction(3, 1))]
>
>  >>> pprint(list(nonredundant_permutations([F(3,1), D(3.0), 3.0])))
> [(Fraction(3, 1), Decimal('3'), 3.0)]
>
> It seems odd to me to want that.  On the other hand, I provide a
> one-line implementation of the desired behavior if anyone wants it.
>   Moreover, I don't think the runtime behavior of my one-liner is
> particularly costly... maybe not the best possible, but the best big-O
> possible.
>
n! gets very big very fast, so that can be a very big set.

If you sort the original items first then it's much easier to yield
unique permutations without having to remember them. (Each would be >
than the previous one, although you might have to map them to orderable
keys if they're not orderable themselves, e.g. a mixture of integers
and strings.)
>
>
> On Fri, Oct 11, 2013 at 1:19 PM, Andrew Barnert <abarnert at yahoo.com
> <mailto:abarnert at yahoo.com>> wrote:
>
>     I think equality is perfectly reasonable here. The fact that {3.0,
>     3} only has one member seems like the obvious precedent to follow here.
>
>     Sent from a random iPhone
>
>     On Oct 11, 2013, at 13:02, David Mertz <mertz at gnosis.cx
>     <mailto:mertz at gnosis.cx>> wrote:
>
>>     What would you like this hypothetical function to output here:
>>
>>     >>> from itertools import permutations
>>     >>> from decimal import Decimal as D
>>     >>> from fractions import Fraction as F
>>     >>> items = (3, 3.0, D(3), F(3,1), "aa", "AA".lower(), "a"+"a")
>>     >>> list(permutations(items))
>>
>>     It's neither QUITE equality nor identity you are looking for, I
>>     think, in nonredundant_permutation():
>>
>>     >> "aa" == "AA".lower(), "aa" is "AA".lower()
>>     (True, False)
>>     >>> "aa" == "a"+"a", "aa" is "a"+"a"
>>     (True, True)
>>     >>> D(3) == 3.0, D(3) is 3.0
>>     (True, False)
>>
>>     On Fri, Oct 11, 2013 at 11:38 AM, Neil Girdhar
>>     <mistersheik at gmail.com <mailto:mistersheik at gmail.com>> wrote:
>>
>>         "It is universally agreed that a list of n distinct symbols
>>         has n! permutations. However, when the symbols are not
>>         distinct, the most common convention, in mathematics and
>>         elsewhere, seems to be to count only distinct permutations." —
>>         http://stackoverflow.com/questions/6534430/why-does-pythons-itertools-permutations-contain-duplicates-when-the-original.
>>
>>
>>         Should we consider fixing itertools.permutations and to output
>>         only unique permutations (if possible, although I realize that
>>         would break code). It is completely non-obvious to have
>>         permutations returning duplicates. For a non-breaking
>>         compromise what about adding a flag?
>>



More information about the Python-ideas mailing list