How to get sliding window of a values for each element in both direction (forward, backward)?

Code:

arr = [1, 2, 3, 4, 5, 6, 7, 8]
window = 3
for backward, current in enumerate(range(len(arr)), start = 0-window):
    if backward < 0:
        backward = 0
    print(arr[current+1:current+1+window], arr[backward:current])

Output:

[2, 3, 4], []
[3, 4, 5], [1]
[4, 5, 6], [1, 2]
[5, 6, 7], [1, 2, 3]
[6, 7, 8], [2, 3, 4]
[7, 8], [3, 4, 5]
[8], [4, 5, 6]
[], [5, 6, 7]

One Liner:

print(dict([(e, (lst[i+1:i+4], lst[max(i-3,0):i])) for i,e in enumerate(last)]))

Output:

{1: ([2, 3, 4], []),
 2: ([3, 4, 5], [1]),
 3: ([4, 5, 6], [1, 2]),
 4: ([5, 6, 7], [1, 2, 3]),
 5: ([6, 7, 8], [2, 3, 4]),
 6: ([7, 8], [3, 4, 5]),
 7: ([8], [4, 5, 6]),
 8: ([], [5, 6, 7])}

Credit: thanks to suggestions from @FeRD and @Androbin, the solution now looks better


This should get you started:

from dataclasses import dataclass
from typing import List

@dataclass
class Window:
  index: int
  backward: List[int]
  forward: List[int]

def window(iterable, window_size, index):
  backward = iterable[max(0, index - window_size):index]
  forward = iterable[index + 1:index + 1 + window_size]
  return Window(index, backward, forward)
>>> window([1,2,3,4,5,6], 3, 0)
Window(index=0, backward=[], forward=[2, 3, 4])
>>> window([1,2,3,4,5,6], 3, 5)
Window(index=5, backward=[3, 4, 5], forward=[])

I would also suggest adding some checks whether the index and window size make sense.

If you are stuck with an older Python version that doesn't have dataclasses yet, you can use Named Tuples instead.


This will work with more_itertools.windowed if you adjust the window size. Since you want 7 items (3 backward, 1 current, 3 forward), set the window size to 7.

from itertools import chain
from more_itertools import windowed
n = 3
iterable = [1, 2, 3, 4, 5, 6, 7, 8]
# pad the iterable so you start with an empty backward window
it = chain([None] * n, iterable, [None] * n)

for window in windowed(it, n * 2 + 1):
    print(window[n])
    print('forward =', [x for x in window[n + 1:] if x is not None])
    print('backward =', [x for x in window[:n] if x is not None])

The output is:

1
forward = [2, 3, 4]
backward = []

2
forward = [3, 4, 5]
backward = [1]

3
forward = [4, 5, 6]
backward = [1, 2]

4
forward = [5, 6, 7]
backward = [1, 2, 3]

5
forward = [6, 7, 8]
backward = [2, 3, 4]

6
forward = [7, 8]
backward = [3, 4, 5]

7
forward = [8]
backward = [4, 5, 6]

8
forward = []
backward = [5, 6, 7]