我有一个坐标列表,我需要根据它们的x值将它们分成两半。像这样:
l = [(0, 0), (1, 0), (2, 0), (3, 0), (0, 1), (1, 1), (2, 1), (3, 1)]
left = []
right = []
for i in l:
if i[0] < 2:
left.append(i)
else:
right.append(i)
print(left)
print(right)
输出:
[(0, 0), (1, 0), (0, 1), (1, 1)]
[(2, 0), (3, 0), (2, 1), (3, 1)]
有更快的方法吗?
答案 0 :(得分:5)
你在O(n)中完成。如果您对列表进行了排序,则可以通过在二进制搜索中搜索pivot元素,在O(log(n))中进行排序。事先对自己进行排序只是为了使用二进制搜索不会得到回报,因为排序是O(n * log(n))
另一方面...... 真的重要吗?如果这是你的瓶颈,那么可能会重新考虑整个算法或数据结构。例如,如果您有一个复杂的问题,您需要在某些区域操作点,您可以考虑使用kd-trees
答案 1 :(得分:1)
这不是更快(2n)但可能更优雅,如果使用二分搜索对列表进行排序,则可以获得最佳效果。
>>> l = [(0, 0), (1, 0), (2, 0), (3, 0), (0, 1), (1, 1), (2, 1), (3, 1)]
>>> left = [ x for x in l if x[0] < 2]
>>> right = [ x for x in l if x[0] >= 2]
答案 2 :(得分:0)
如果您希望它更简洁,更具抒情性和可读性,而不会失去O(n)性能,这可能是其中一种方式 -
right = []
left = [coord for coord in l if (lambda t: True if t[0] < 2 else right.append(t) and False)(coord)]
仅在列表中迭代一次。
>>> l = [(0, 0), (1, 0), (2, 0), (3, 0), (0, 1), (1, 1), (2, 1), (3, 1)]
>>> right = []
>>> left = [coord for coord in l if (lambda t: True if t[0] < 2 else right.append(t) and False)(coord)]
>>> print '\n'.join([str(left), str(right)])
[(0, 0), (1, 0), (0, 1), (1, 1)]
[(2, 0), (3, 0), (2, 1), (3, 1)]
>>>