Python 将列表分组为子列表,这些列表是单调的,元素之间的差异相等
Python group list to sub-lists lists that are monotonic with equal diff between elements
l = [2,4,6,12,14,16,21,27,29,31]
我想把它拆分成列表,这样每个列表的元素都是一个单调列表,元素之间的差异为 2:
new_l = [[2,4,6], [12,14,16],[21], [27,29,31]]
最有效的方法是什么?
更新
可以完全避免 Python 循环,只使用 comprehensions
(连同 zip
)来提高效率。您可以按照以下方式进行操作:
l = [2,4,6,12,14,16,21,27,29,31, 44]
n = len(l)
#Find the splitting points (where the monotonic condition breaks):
splitting_points = [0] + [k for k in range(1, n) if l[k] - l[k - 1] != 2]
if splitting_points[-1] != n:
splitting_points.append(n)
#Then split the list into intervals having bounds in the splitting_points:
new_l = [l[i: j] for i, j in zip(splitting_points[:-1], splitting_points[1:])]
print(new_l)
这个“应该”比循环快得多(尤其是对于大型列表),但我没有做过任何基准测试。
原创
您必须遍历初始列表 l
,维护具有当前单调序列的当前列表,每当新的迭代元素打破单调条件时,插入当前列表并将其清除。
下面是一段代码,正是这样做的:
l = [2,4,6,12,14,16,21,27,29,31]
new_l = []
current_l = [l[0]] #initially, insert the first element
for k in range(1, len(l)):
if l[k] - current_l[-1] == 2: #if the monotonic condition is satisfied
current_l.append(l[k]) #we append the element
else:
new_l.append(current_l) #otherwise, we append the previous list to the answer
current_l = [l[k]] #and clear the running sequence
new_l.append(current_l) #there will always be a last sequence not appended to the answer
print(new_l)
您可以确定要拆分的索引,然后像这样应用 np.split
:
np.split(l, np.flatnonzero(np.diff(l)!=2) + 1)
输出:
[array([2, 4, 6]), array([12, 14, 16]), array([21]), array([27, 29, 31])]
然而,使用不同长度的数组从来都不是高效的,所以这就是 np.split
相当慢的原因。
l = [2,4,6,12,14,16,21,27,29,31]
我想把它拆分成列表,这样每个列表的元素都是一个单调列表,元素之间的差异为 2:
new_l = [[2,4,6], [12,14,16],[21], [27,29,31]]
最有效的方法是什么?
更新
可以完全避免 Python 循环,只使用 comprehensions
(连同 zip
)来提高效率。您可以按照以下方式进行操作:
l = [2,4,6,12,14,16,21,27,29,31, 44]
n = len(l)
#Find the splitting points (where the monotonic condition breaks):
splitting_points = [0] + [k for k in range(1, n) if l[k] - l[k - 1] != 2]
if splitting_points[-1] != n:
splitting_points.append(n)
#Then split the list into intervals having bounds in the splitting_points:
new_l = [l[i: j] for i, j in zip(splitting_points[:-1], splitting_points[1:])]
print(new_l)
这个“应该”比循环快得多(尤其是对于大型列表),但我没有做过任何基准测试。
原创
您必须遍历初始列表 l
,维护具有当前单调序列的当前列表,每当新的迭代元素打破单调条件时,插入当前列表并将其清除。
下面是一段代码,正是这样做的:
l = [2,4,6,12,14,16,21,27,29,31]
new_l = []
current_l = [l[0]] #initially, insert the first element
for k in range(1, len(l)):
if l[k] - current_l[-1] == 2: #if the monotonic condition is satisfied
current_l.append(l[k]) #we append the element
else:
new_l.append(current_l) #otherwise, we append the previous list to the answer
current_l = [l[k]] #and clear the running sequence
new_l.append(current_l) #there will always be a last sequence not appended to the answer
print(new_l)
您可以确定要拆分的索引,然后像这样应用 np.split
:
np.split(l, np.flatnonzero(np.diff(l)!=2) + 1)
输出:
[array([2, 4, 6]), array([12, 14, 16]), array([21]), array([27, 29, 31])]
然而,使用不同长度的数组从来都不是高效的,所以这就是 np.split
相当慢的原因。