在约束下创建对的组列表

时间:2018-01-17 15:17:36

标签: python algorithm

我试图在给定对的列表的情况下创建一组对的列表,例如[(a1,b1), (a2,b2)...],使得每个结果组中的所有元组都满足约束

abs(ai - aj) < 2abs(bi - bj) < 3

例如,给定:

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

结果将是3组的列表:

[[(1, 2), (2, 3)], [(6, 4), (7, 5)], [(8, 15)]]。类似地:

  • [(1, 2), (2, 3), (6, 2), (9, 3), (10, 4)] - &gt; [[(1, 2), (2, 3)], [(6, 2)], [(9, 3), (10, 4)]]

  • [(1, 2), (2, 3), (6, 2), (7, 4), (8, 15)] - &gt; [[(1, 2), (2, 3)], [(6, 2), (7, 4)], [(8, 15)]]

有没有人知道创建群组的有效方法?

2 个答案:

答案 0 :(得分:0)

您可以使用itertools.groupby

import itertools
s = [(1,2),(2,3),(6,4),(7,5),(8,15)]
new_data = [d for c, d in [(a, list(b)) for a, b in itertools.groupby(s, key=lambda (x, y):(abs(x-y) < 2, abs(x-y) < 3))]]

输出:

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

由于上面的回答使用了lambda元组解包,因此它不适用于Python3。但是,对于兼容Python3的解决方案,请使用以下代码:

import itertools
s = [(1,2),(2,3),(6,4),(7,5),(8,15)]
new_data = [d for c, d in [(a, list(b)) for a, b in itertools.groupby(s, key=lambda x:(abs(x[0]-x[1]) < 2, abs(x[0]-x[1]) < 3))]]

答案 1 :(得分:0)

你在找这样的东西吗?

不使用任何只有一个循环的外部库:

data=[(1,2),(2,3),(6,4),(7,5),(8,15)]


print([(lambda x:x if abs(x[0][0]-x[1][0])<2 and abs(x[0][1]-x[1][1]<3) else 0)(data[i:i+2]) if len(data[i:i+2])>1 else data[i:i+2] for i in range(0, len(data), 2)])

输出:

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

使用itertool的东西(但是检查每个元素,所以如果你想要这样的东西,结果会有所不同)

import itertools
data=[(1,2),(2,3),(6,4),(7,5),(8,15)]



print(list(filter(lambda y:y!=0,[(lambda x:x if abs(x[0][0]-x[1][0])<2 and abs(x[0][1]-x[1][1]<3) else 0)(i) for i in itertools.combinations(data, r=2)])))

更新代码:

data=[(1, 2), (2, 3), (6, 2), (9, 3), (10, 4)]


print(list(filter(lambda y:y!=0,[(lambda x:x if abs(x[0][0]-x[1][0])<2 and abs(x[0][1]-x[1][1]<3) else 0)(data[i:i+2]) if len(data[i:i+2])>1 else data[i:i+2] for i in range(0, len(data), 2)])))

输出:

[[(1, 2), (2, 3)], [(10, 4)]]

P.S:如果这个解决方案可以帮助你,请不要接受答案,只需使用它。