2016-10-27 41 views
0

我有一個元組列表,看起來像這樣:在元組列表,找到一個匹配,如果某個字段設置

[ 
(36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), 
(36, 0, 184187.125, 148323.234375, 55, 3), 
(140, 0, 0.0, 0.0, 34, 1), 
(141, 0, 6.35533332824707, 5.926896095275879, 22, 2) 
] 

我想通過列表進行迭代,並且如果第二字段在元組中是'1',那麼我想找到與第一個字段匹配的任何東西,並將這兩個元組作爲新元組(或其他數據結構;不必是元組)在一個列表中返回火柴。因此,在這個例子中,輸出會是這樣的:

[(
(36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), 
(36, 0, 184187.125, 148323.234375, 55, 3) 
)] 

我在一個小的損失從哪裏開始的這一點沒有進入一個非常緩慢的爲O(n^n)的那種情況。

+0

元組是連續的?我的意思是當你找到1時,你只返回當前元組和下一個元組? –

+0

@ Jean-FrançoisFabre,不一定,至少目前。雖然也許有一種方法來排序清單,以便發生? – septagram

回答

1

下面是一些代碼來處理元組列表,而不是假設列表正確排序。

  • 第一排序與根據第一值和第二值的元組的列表1(發出一個布爾),因此元組被「分組」由第一「列」,和1所發生的歷史第一元組的列表。排序是不O(n**2),大概O(log(n)*n)
  • 然後撰寫使用groupby到組根據所述第一值(第二值「1」還是被第一分組時)
  • 終於濾除基團,其中1是不存在元組生成器表達式

最後一步是O(n)。下面的代碼:

from itertools import groupby 

tuple_list = [ 
(36, 0, 184187.125, 148323.234375, 55, 3), 
(140, 0, 0.0, 0.0, 34, 1), 
(141, 0, 6.35533332824707, 5.926896095275879, 22, 2), 
(36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), 
] 

ones_first = (sorted(tuple_list,key=lambda r : (r[0],r[1]!=1))) 
tuples = (tuple(x for x in y) for _,y in groupby(ones_first,key=lambda r : r[0])) 

with_ones = tuple(filter(lambda r : r[0][1]==1,tuples)) 
print(with_ones) 

結果:

(((36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), (36, 0, 184187.125, 148323.234375, 55, 3)),) 
1
lst=[ 
(36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), 
(36, 0, 184187.125, 148323.234375, 55, 3), 
(140, 0, 0.0, 0.0, 34, 1), 
(141, 0, 6.35533332824707, 5.926896095275879, 22, 2) 
] 

這裏有一個行嵌套的for循環列表理解:

out=[y for x in lst if x[1]==1 for y in lst if y[0]==x[0]] 
print(out) 
[(36, 1, 2908.8037109375, 1835.6429443359375, 17, 0), (36, 0, 184187.125, 148323.234375, 55, 3)] 

如果你有很多lst元組的話就不會有搜索結果比這更快的方式。

相關問題