在不使用列表长度的情况下迭代子列表

问题描述

我有一个东西列表,我需要对3个元素的连续(和重叠)组进行一些处理:

我可以做到:

for i in range(len(things)-2):
    process(things[i:i+3])

例如:

things=[0,1,2,3,4,5,6,7]

我要处理:

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

但是有一种聪明(但可读)的方法来执行此操作,而无需显式使用len(things)

解决方法

是的,您要查找的是一个滑动/移动窗口。有多种方法可以实现此目的,但最简单的方法是使用tee()中的islice()itertools函数。使用此方法,您可以定义一个window()函数,如下所示,默认窗口大小为2。

import itertools

def window(iterable,n=2):
    iters = itertools.tee(iterable,n)
    for i,it in enumerate(iters):
        next(itertools.islice(it,i,i),None)
    return zip(*iters)

然后您可以将其用作

>>> things=[0,1,2,3,4,5,6,7]
>>> list(window(things,n = 3))
[(0,2),(1,3),(2,4),(3,5),(4,6),(5,7)]
>>> for elem in window(things,n = 3):
...     print(elem)
... 
(0,2)
(1,3)
(2,4)
(3,5)
(4,6)
(5,7)

编辑:有一次,使用更简单的选项可能是

>>> list(zip(things,things[1:],things[2:]))
[(0,7)]
,

另一种实现方式可能是:

for i in things[0:-2]:
    a=things.index(i)
    process(things[a:a+3])
,

让我们尝试使用enumerate,这里len(things[i : i+len_]) == len_是要删除大小不一的列表,这些列表将在最终迭代中累加。

len_ = 3

[things[i : i+len_] for i,j in enumerate(things) if len(things[i : i+len_]) == len_]

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

len_ = 4

[things[i : i+len_] for i,7]]