Skip to content

Commit 13d7125

Browse files
committed
Add helper function to generate sliding windows of length N over iterable
Function `sliding_window` copied from https://docs.python.org/3/library/itertools.html#itertools-recipes
1 parent 79fce2a commit 13d7125

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

commodore/helpers.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import collections
2+
import itertools
23
import json
34
import shutil
45
import os
@@ -228,3 +229,14 @@ def relsymlink(src: P, dest_dir: P, dest_name: Optional[str] = None):
228229
if link_dst.exists():
229230
os.remove(link_dst)
230231
os.symlink(link_src, link_dst)
232+
233+
234+
def sliding_window(iterable, n):
235+
# sliding_window('ABCDEFG', 4) -> ABCD BCDE CDEF DEFG
236+
it = iter(iterable)
237+
window = collections.deque(itertools.islice(it, n), maxlen=n)
238+
if len(window) == n:
239+
yield tuple(window)
240+
for x in it:
241+
window.append(x)
242+
yield tuple(window)

tests/test_helpers.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,33 @@ def test_yaml_dump(tmp_path: Path, input, expected):
134134
)
135135
def test_yaml_dump_all(tmp_path: Path, input, expected):
136136
_test_yaml_dump_fun(helpers.yaml_dump_all, tmp_path, input, expected)
137+
138+
139+
@pytest.mark.parametrize(
140+
"sequence,winsize,expected",
141+
[
142+
(
143+
"abcd",
144+
1,
145+
[("a",), ("b",), ("c",), ("d",)],
146+
),
147+
(
148+
"abcd",
149+
2,
150+
[("a", "b"), ("b", "c"), ("c", "d")],
151+
),
152+
(
153+
"abcd",
154+
4,
155+
[("a", "b", "c", "d")],
156+
),
157+
(
158+
["aaa", "bbb", "ccc", "ddd"],
159+
2,
160+
[("aaa", "bbb"), ("bbb", "ccc"), ("ccc", "ddd")],
161+
),
162+
],
163+
)
164+
def test_sliding_window(sequence, winsize, expected):
165+
windows = list(helpers.sliding_window(sequence, winsize))
166+
assert windows == expected

0 commit comments

Comments
 (0)