在 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
的解决方案,只使用索引 range
、len
和 list 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]]
假设我有一个从 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
的解决方案,只使用索引 range
、len
和 list 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]]