Skip to content

Commit

Permalink
Merge 2087608 into 6182a61
Browse files Browse the repository at this point in the history
  • Loading branch information
rominf committed Mar 23, 2019
2 parents 6182a61 + 2087608 commit 7556ce3
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
30 changes: 29 additions & 1 deletion more_itertools/more.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from sys import maxsize, version_info
from collections.abc import Sequence

from .recipes import consume, flatten, take
from .recipes import consume, flatten, powerset, take

__all__ = [
'adjacent',
Expand Down Expand Up @@ -54,6 +54,7 @@
'numeric_range',
'one',
'padded',
'partitions',
'peekable',
'replace',
'rlocate',
Expand Down Expand Up @@ -2306,3 +2307,30 @@ def replace(iterable, pred, substitutes, count=None, window_size=1):
# yield the first item from the window.
if w and (w[0] is not _marker):
yield w[0]


def _is_collection(iterable):
return hasattr(iterable, '__getitem__') and hasattr(iterable, '__len__')


def partitions(iterable):
"""Yield all possible partitions of *iterable*.
Partition x is defined so that:
1. list(x) = [x_0, ..., x_n]
2. x_0 + ... + x_n = list(iterable)
3. all(isinstance(x_i, (type(iterable), list)) for x_i in x) == True
4. 1 <= n <= ilen(iterable)
5. isinstance(x, list) == True
>>> iterable = 'abcd'
>>> list(partitions(iterable))
[['abcd'], ['a', 'bcd'], ['ab', 'cd'], ['abc', 'd'], \
['a', 'b', 'cd'], ['a', 'bc', 'd'], ['ab', 'c', 'd'], ['a', 'b', 'c', 'd']]
"""
collection = iterable if _is_collection(iterable) else list(iterable)
n = len(collection)
if n > 0:
for partition_indexes in powerset(range(1, n)):
yield [collection[i:j] for i, j in zip((0, ) + partition_indexes,
partition_indexes + (n, ))]
23 changes: 23 additions & 0 deletions more_itertools/tests/test_more.py
Original file line number Diff line number Diff line change
Expand Up @@ -2311,3 +2311,26 @@ def test_iterable_substitutes(self):
actual = list(mi.replace(iterable, pred, substitutes))
expected = ['_', '_', 1, '_', '_', 3, '_', '_']
self.assertEqual(actual, expected)


class PartitionsTest(TestCase):
def test_basic(self):
iterable = 'abcd'
actual = list(mi.partitions(iterable))
expected = [
['abcd'],
['a', 'bcd'],
['ab', 'cd'],
['abc', 'd'],
['a', 'b', 'cd'],
['a', 'bc', 'd'],
['ab', 'c', 'd'],
['a', 'b', 'c', 'd']
]
self.assertEqual(actual, expected)

def test_empty(self):
iterable = []
actual = list(mi.partitions(iterable))
expected = []
self.assertEqual(actual, expected)

0 comments on commit 7556ce3

Please sign in to comment.