在 Python 中将序列拆分为各个步骤的最优雅方式

Most elegant way to split a sequence into individual steps in Python

假设我有一个从 0 到 9 的列表:

lst = list(range(10))

我想将其拆分为 2 个单独的步骤。我设法编写了以下工作代码:

res = [[] for _ in range(len(lst) - 1)]
for i, x in enumerate(lst):
    if i < len(lst) - 1:
        res[i].append(x)
    if i > 0:
        res[i-1].append(x)

>>> print(res)
[[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9]]

但我觉得应该有更优雅的编码方式。有什么建议吗?

您可以将 zip 函数与列表理解一起使用。

>>> lst = list(range(10))
>>> [list(elm) for elm in zip(lst, lst[1:])]
[[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9]]

对于元组列表:

>>> list(zip(lst,lst[1:]))
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)]

对于列表列表:

>>> list(map(list, zip(lst,lst[1:])))
[[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9]]

您可以概括为 n 个步骤:

def steps(lst, n=2):
    return [[*x] for x in zip(*(lst[i:] for i in range(n)))]

steps(range(10), 2)
# [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9]]
steps(range(10), 3)
# [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, 8], [7, 8, 9]]

这是一个没有 zip 的解决方案,只使用索引 rangelenlist comprehension:

lst = list(range(10))
res = [ [lst[i], lst[i+1]] for i in range(len(lst) - 1)]
print(res)
# [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9]]

您可以完全避免 zip,只需使用列表理解来创建滑动 window。

[lst[i: i + 2] for i in range(0, len(lst) - 1)]
>> [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9]]