使用 for 和 while 循环对列表中的每个第 n 个范围进行切片

Slicing every nth range within a list with a for and a while loop

所以我有一个名为 someList 的简短列表,其中包含一些数字。我想要做的是输出列表的每 3 个元素,同时每第 3 个切片范围对其进行迭代。

所以如果我有

someList = [1,2,3,4,5,6,7,8,9,10]

我的 someList 的输出应该是这样的

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

这是我的代码,我在其中定义了一个新的 temp 列表来存储输出值

someList = [1,2,3,4,5,6,7,8,9,10]
lookupRange = 3
temp = []
for index,i in enumerate(someList):
    while index <= len(someList):
        temp.append(someList[index:index+lookupRange])
        index += 1            

print(temp)

但是在 运行 这段代码中我得到了一些意想不到的结果...

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

如您所见,对于前几行,我确实获得了切片范围周期为 3 的所需输出。但之后它就变得疯狂了...

关于这里出了什么问题有什么想法吗?

PS:我知道可能有更简单的一种线性方法来做到这一点(例如 numpy.convolve 函数),但这个问题特别需要我只用 for 和 while 循环来做.

你有嵌套循环,但你只需要一个循环。

someList = [1,2,3,4,5,6,7,8,9,10]
lookupRange = 3
temp = []
for index in range(len(someList) - lookupRange + 1):
    temp.append(someList[index:index+lookupRange])

使用列表理解:

>>> someList = [1,2,3,4,5,6,7,8,9,10]
>>> chunk = 3
>>> [someList[i : i + chunk] for i in range(len(someList) - chunk + 1)]
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, 8], [7, 8, 9], [8, 9, 10]]

这是一个纯粹的 Python 单行;不需要 Numpy。

someList = [1,2,3,4,5,6,7,8,9,10]
lookupRange = 3
temp = list(zip(*(someList[i:] for i in range(lookupRange))))
print(temp)

输出

[(1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7), (6, 7, 8), (7, 8, 9), (8, 9, 10)]

在Python2中,对temp的赋值可以简化为

temp = zip(*(someList[i:] for i in range(lookupRange)))

如果您确实需要列表列表而不是元组列表,您可以将其更改为

temp = [list(u) for u in zip(*(someList[i:] for i in range(lookupRange)))]

在 Python 2 或 3 中同样有效。

但我会坚持使用元组(除非您需要改变那些内部列表):元组使用更少的 RAM,并且使用元组的代码通常比等效的基于列表的代码更快。


这是最后一个版本,它使用几个传统的 for 循环而不是嵌套在列表推导中的生成器表达式。

someList = [1,2,3,4,5,6,7,8,9,10]
lookupRange = 3

offset_lists = []
for i in range(lookupRange):
    offset_lists.append(someList[i:])

temp = []
for u in zip(*offset_lists):
    temp.append(list(u))
print(temp)

输出

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