Skip to content

Commit

Permalink
Merge pull request #606 from more-itertools/subslices
Browse files Browse the repository at this point in the history
Add subslices recipe
  • Loading branch information
bbayles committed Apr 19, 2022
2 parents d971c86 + 74bc878 commit 59aeef1
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
15 changes: 15 additions & 0 deletions more_itertools/recipes.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
'repeatfunc',
'roundrobin',
'sliding_window',
'subslices',
'tabulate',
'tail',
'take',
Expand Down Expand Up @@ -767,3 +768,17 @@ def sliding_window(iterable, n):
for x in it:
window.append(x)
yield tuple(window)


def subslices(iterable):
"""Return all contiguous non-empty subslices of *iterable*.
>>> list(subslices('ABC'))
[['A'], ['A', 'B'], ['A', 'B', 'C'], ['B'], ['B', 'C'], ['C']]
This is similar to :func:`substrings`, but emits items in a different
order.
"""
seq = list(iterable)
slices = starmap(slice, combinations(range(len(seq) + 1), 2))
return map(operator.getitem, repeat(seq), slices)
1 change: 1 addition & 0 deletions more_itertools/recipes.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,4 @@ def triplewise(iterable: Iterable[_T]) -> Iterator[Tuple[_T, _T, _T]]: ...
def sliding_window(
iterable: Iterable[_T], n: int
) -> Iterator[Tuple[_T, ...]]: ...
def subslices(iterable: Iterable[_T]) -> Iterator[List[_T]]: ...
29 changes: 29 additions & 0 deletions tests/test_recipes.py
Original file line number Diff line number Diff line change
Expand Up @@ -806,3 +806,32 @@ def test_basic(self):
with self.subTest(expected=expected):
actual = list(mi.sliding_window(iterable, n))
self.assertEqual(actual, expected)


class SubslicesTests(TestCase):
def test_basic(self):
for iterable, expected in [
([], []),
([1], [[1]]),
([1, 2], [[1], [1, 2], [2]]),
(iter([1, 2]), [[1], [1, 2], [2]]),
([2, 1], [[2], [2, 1], [1]]),
(
'ABCD',
[
['A'],
['A', 'B'],
['A', 'B', 'C'],
['A', 'B', 'C', 'D'],
['B'],
['B', 'C'],
['B', 'C', 'D'],
['C'],
['C', 'D'],
['D'],
],
),
]:
with self.subTest(expected=expected):
actual = list(mi.subslices(iterable))
self.assertEqual(actual, expected)

0 comments on commit 59aeef1

Please sign in to comment.