2013-04-28 123 views
0

我有一個座標列表,我需要根據它們的x值將它們分成兩半。事情是這樣的:Python,分割座標列表,基於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)] 

有一個更快的方法來做到這一點?

+1

你在一個循環中做,所以基本上我不認爲有更快的方法。 – 2013-04-28 20:34:52

+2

相關:http://stackoverflow.com/q/949098/951890 – 2013-04-28 20:36:13

+1

你的代碼在性能上是好的。 @LevLevitsky是對的,肯定可以寫出更快的方法,但性能差異應該可以忽略不計。 – vaultah 2013-04-28 20:38:31

回答

1

這不是更快(2n),但也許更優雅,如果列表使用二分搜索進行排序,您可以得到的最好記錄是n。

>>> 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] 
5

你在O(n)中做。如果您已經對列表進行了排序,則可以在O(log(n))中執行此操作,方法是使用二分搜索搜索主元素。自己排序它只是爲了使用二進制搜索不會得到回報,因爲排序是O(n * log(n))

另一方面... 它真的很重要嗎?如果這是你的瓶頸,那麼可能重新考慮整個算法或數據結構。例如,如果您有一個複雜的問題,需要在某些區域的點上操作,則可以考慮使用kd-trees

0

如果您希望它更簡潔一些,pythonic和可讀的,而不會丟失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)] 
>>>