[Python-ideas] Another "little" combination, permutation, iterator, yield from, example.

Tim Peters tim.peters at gmail.com
Wed Oct 16 02:25:13 CEST 2013


[Tim]
>> [MRAB, posts a beautiful solution]
>>
>> I don't really have a use for this, but it was a lovely programming
>> puzzle, so I'll include an elaborate elaboration of MRAB's algorithm
>> below.  And that's the end of my interest in this;-)

[Ron Adam]
> A what the heck...  :-)
>
>
> This is what I came up with which works like MRAB's by removing the first
> element and using recursion on the rest.  (It's how you do it in lisp or
> scheme.)

It's solving a different problem, though.  In your "Return all unique
combinations of elements in seq", by "unique" you really mean "by
position", not " by value".  For example:

>>>  for p in unique_sets('aab'):
...        print(p)
['a']
['a']
['b']
['b', 'a']
['a', 'a']
['b', 'a']
['b', 'a', 'a']

See?  ['a'] is produced twice, and so is ['b', 'a'].  The whole point
of the algorithms in the thread this spawned from was to avoid
generating *value*-duplicates to begin with.  Filtering them out later
is too inefficient.

>>> for p in unique_sets('aaaaaaaaaa'):
...        print(p)
['a']
['a']
['a']
['a']
['a']
['a']
['a']
['a']
['a']
['a']
['a', 'a']
['a', 'a']
['a', 'a']
['a', 'a', 'a']
['a', 'a']
['a', 'a']
['a', 'a']
['a', 'a', 'a']
... on and on and on ....

Only one comment on the code:


> def unique_sets(seq):
>     """Return all unique combinations of elements in seq."""
>     if len(seq) == 0:
>         return []
>     first, rest = seq[0], seq[1:]

Python's newer unpacking syntax makes that one prettier:

    first, *rest = seq

Much higher-level than crusty old Lisp or Scheme ;-)

> ....


More information about the Python-ideas mailing list