Rolling or sliding window iterator?

后端 未结 23 1394
南方客
南方客 2020-11-21 05:23

I need a rolling window (aka sliding window) iterable over a sequence/iterator/generator. Default Python iteration can be considered a special case, where the window length

23条回答
  •  孤街浪徒
    2020-11-21 06:02

    Here's a generalization that adds support for step, fillvalue parameters:

    from collections import deque
    from itertools import islice
    
    def sliding_window(iterable, size=2, step=1, fillvalue=None):
        if size < 0 or step < 1:
            raise ValueError
        it = iter(iterable)
        q = deque(islice(it, size), maxlen=size)
        if not q:
            return  # empty iterable or size == 0
        q.extend(fillvalue for _ in range(size - len(q)))  # pad to size
        while True:
            yield iter(q)  # iter() to avoid accidental outside modifications
            try:
                q.append(next(it))
            except StopIteration: # Python 3.5 pep 479 support
                return
            q.extend(next(it, fillvalue) for _ in range(step - 1))
    

    It yields in chunks size items at a time rolling step positions per iteration padding each chunk with fillvalue if necessary. Example for size=4, step=3, fillvalue='*':

     [a b c d]e f g h i j k l m n o p q r s t u v w x y z
      a b c[d e f g]h i j k l m n o p q r s t u v w x y z
      a b c d e f[g h i j]k l m n o p q r s t u v w x y z
      a b c d e f g h i[j k l m]n o p q r s t u v w x y z
      a b c d e f g h i j k l[m n o p]q r s t u v w x y z
      a b c d e f g h i j k l m n o[p q r s]t u v w x y z
      a b c d e f g h i j k l m n o p q r[s t u v]w x y z
      a b c d e f g h i j k l m n o p q r s t u[v w x y]z
      a b c d e f g h i j k l m n o p q r s t u v w x[y z * *]
    

    For an example of use case for the step parameter, see Processing a large .txt file in python efficiently.

提交回复
热议问题