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

David Mertz mertz at gnosis.cx
Sat Oct 12 00:45:04 CEST 2013


I realize after reading
http://stackoverflow.com/questions/6284396/permutations-with-unique-valuesthat
my version was ALMOST right:

def nonredundant_permutations(seq, r=None):
    last = ()
    for perm in permutations(sorted(seq), r):
        if perm > last:
            yield perm
            last = perm

I can't look only for inequality, but must use the actual comparison.

>>> ["".join(x) for x in nonredundant_permutations('aaabb',3)]
['aaa', 'aab', 'aba', 'abb', 'baa', 'bab', 'bba']
>>> list(nonredundant_permutations([F(3,1), D(3.0), 3.0]))
[(Fraction(3, 1), Decimal('3'), 3.0)]

Of course, this approach DOES rely on the order in which
itertools.permutations() returns values.  However, it's a bit more compact
than MRAB's version.




On Fri, Oct 11, 2013 at 3:23 PM, Neil Girdhar <mistersheik at gmail.com> wrote:

> Beautiful!!
>
>
> On Fri, Oct 11, 2013 at 6:19 PM, MRAB <python at mrabarnett.plus.com> wrote:
>
>> On 11/10/2013 23:03, David Mertz wrote:
>>
>>> Bummer.  You are right, Neil.  I saw MRAB's suggestion about sorting,
>>> and falsely thought that would be general; but obviously it's not.
>>>
>>> So I guess the question is whether there is ANY way to do this without
>>> having to accumulate a 'seen' set (which can grow to size N!).  The
>>> answer isn't jumping out at me, but that doesn't mean there's not a way.
>>>
>>> I don't want itertools.permutations() to do "equality filtering", but
>>> assuming some other function in itertools were to do that, how could it
>>> do so algorithmically? Or whatever, same question if it is
>>> itertools.permutations(seq, distinct=True) as the API.
>>>
>>>  Here's an implementation:
>>
>> def unique_permutations(iterable, count=None, key=None):
>>     def perm(items, count):
>>         if count:
>>             prev_item = object()
>>
>>             for i, item in enumerate(items):
>>                 if item != prev_item:
>>                     for p in perm(items[ : i] + items[i + 1 : ], count -
>> 1):
>>                         yield [item] + p
>>
>>                 prev_item = item
>>
>>         else:
>>             yield []
>>
>>     if key is None:
>>         key = lambda item: item
>>
>>     items = sorted(iterable, key=key)
>>
>>     if count is None:
>>         count = len(items)
>>
>>     yield from perm(items, count)
>>
>>
>> And some results:
>>
>> >>> print(list("".join(x) for x in unique_permutations('aaabb', 3)))
>> ['aaa', 'aab', 'aba', 'abb', 'baa', 'bab', 'bba']
>> >>> print(list(unique_**permutations([0, 'a', 0], key=str)))
>> [[0, 0, 'a'], [0, 'a', 0], ['a', 0, 0]]
>>
>>
>> ______________________________**_________________
>> Python-ideas mailing list
>> Python-ideas at python.org
>> https://mail.python.org/**mailman/listinfo/python-ideas<https://mail.python.org/mailman/listinfo/python-ideas>
>>
>> --
>>
>> --- You received this message because you are subscribed to a topic in
>> the Google Groups "python-ideas" group.
>> To unsubscribe from this topic, visit https://groups.google.com/d/**
>> topic/python-ideas/**dDttJfkyu2k/unsubscribe<https://groups.google.com/d/topic/python-ideas/dDttJfkyu2k/unsubscribe>
>> .
>> To unsubscribe from this group and all its topics, send an email to
>> python-ideas+unsubscribe@**googlegroups.com<python-ideas%2Bunsubscribe at googlegroups.com>
>> .
>> For more options, visit https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out>
>> .
>>
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
>
>


-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131011/596d16ea/attachment.html>


More information about the Python-ideas mailing list