5
\$\begingroup\$

I had to write a code for finding all non-empty sublists partitionings of a list:

def f(s):
    if s:
        for j in range(1,len(s)+1):
            for p in f(s[j:]):
                yield [s[:j]]+p
    else:
        yield []

I managed to shorten it (for Python 3.4+) to:

def f(s, p=[]):
    if s:
        for j in range(1,len(s)+1):
            yield from f(s[j:],p+[s[:j]])
    else:
        yield p

using yield from and an accumulator argument p (prefix).

Any suggestions on how to shorten it even more?

Example output:

>>> for p in f([1,2,3,4]): print(p)
...
[[1], [2], [3], [4]]
[[1], [2], [3, 4]]
[[1], [2, 3], [4]]
[[1], [2, 3, 4]]
[[1, 2], [3], [4]]
[[1, 2], [3, 4]]
[[1, 2, 3], [4]]
[[1, 2, 3, 4]]
>>>
\$\endgroup\$
  • 3
    \$\begingroup\$ For starters, you can use single char variable names and drop a bunch of whitespace \$\endgroup\$ – Sp3000 Jul 13 '15 at 13:25
  • 1
    \$\begingroup\$ Can we answer with code in other languages, too? This would work pretty well as a language agnostic challenge. \$\endgroup\$ – John Dvorak Jul 13 '15 at 13:37
  • \$\begingroup\$ @JanDvorak This is asking for help in golfing the python program. \$\endgroup\$ – Okx May 18 '17 at 15:24
  • \$\begingroup\$ @okx hence my trying to convert this into a regular challenge via my comment. The answer would carry over just fine. \$\endgroup\$ – John Dvorak May 18 '17 at 15:28
3
\$\begingroup\$

66 bytes

p=lambda l:[q+[l[i:]]for i in range(len(l))for q in p(l[:i])]or[l]

If the last part is changed from [l] to [[]], then it can also be used with tuples or strings, in addition to lists.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.