2017-02-01 104 views
2

有沒有一種方法可以根據元組中的索引刪除重複的元組。說我有根據元組中的索引刪除重複的元組值

[(0, 4, 1.0), (1, 4, 1.0), (3, 4, 1.0), (0, 3, 2.0), (1, 3, 2.0), (0, 2, 3.0), (1, 2, 3.0), (2, 4, 4.0), (2, 3, 5.0), (0, 1, inf)] 

我可以隨機保留一個元組,其中每個副本在索引2處具有相同的值嗎?

因此,有三個元組在索引2處具有值1.0,兩個元組在索引2處具有值2.0,一個在索引2處具有值3,依此類推。 (0,4,1.0)可以從索引2處的值1.0中隨機地選擇,並且(1,3,2.0)可以從索引2處的值2.0中隨機地選擇。 說,(1,3,2.0) 2,3.0)的隨機值3.0的指數選擇2 然後,我的名單看起來像

[(0, 4, 1.0),(1, 3, 2.0), (1, 2, 3.0), (2, 4, 4.0), (2, 3, 5.0), (0, 1, inf)] 

我從來沒有碰到過,這是否或至少有效的功能。

+0

都與相同的值索引2元組在輸入中彼此相鄰?如果不是輸出的正確順序是什麼? – niemmi

+0

我可以對它們進行排序,就像它們高於 –

回答

4

你可以在索引2.使用itertools.groupby到組基於價值的元組然後爲每個組可以使用random.choice選擇一個元組:

>>> from itertools import groupby 
>>> import random 
>>> l = [(0, 4, 1.0), (1, 4, 1.0), (3, 4, 1.0), (0, 3, 2.0), (1, 3, 2.0), (0, 2, 3.0), (1, 2, 3.0), (2, 4, 4.0), (2, 3, 5.0), (0, 1, float('inf'))] 
>>> [random.choice(tuple(g)) for _, g in groupby(l, key=lambda x: x[2])] 
[(1, 4, 1.0), (1, 3, 2.0), (1, 2, 3.0), (2, 4, 4.0), (2, 3, 5.0), (0, 1, inf)] 

在上面groupby回報可迭代(key, group)元組,其中關鍵是值通過第二個參數返回給groupby和組是可迭代的元素的組內:

>>> [(k, tuple(g)) for k, g in groupby(l, key=lambda x: x[2])] 
[(1.0, ((0, 4, 1.0), (1, 4, 1.0), (3, 4, 1.0))), (2.0, ((0, 3, 2.0), (1, 3, 2.0))), (3.0, ((0, 2, 3.0), (1, 2, 3.0))), (4.0, ((2, 4, 4.0),)), (5.0, ((2, 3, 5.0),)), (inf, ((0, 1, inf),))] 

因爲我們不需要的關鍵,我們可以放棄它並轉換組到序列random.choice預計:

>>> [random.choice(tuple(g)) for _, g in groupby(l, key=lambda x: x[2])] 
[(1, 4, 1.0), (1, 3, 2.0), (0, 2, 3.0), (2, 4, 4.0), (2, 3, 5.0), (0, 1, inf)] 

注意,上述預期與相同值元組索引2是在輸入彼此相鄰。如果不是這種情況,您可以在將原始列表傳遞到groupby之前對其進行排序。

更新如果你只是想要的結果,你可以用它代替列表理解發電機表達,並從那裏獲取值出與islice的三個第一值:

>>> from itertools import islice 
>>> gen = (random.choice(tuple(g)) for _, g in groupby(l, key=lambda x: x[2])) 
>>> list(islice(gen, 3)) 
[(0, 4, 1.0), (1, 3, 2.0), (0, 2, 3.0)] 
+0

注意:列表應該根據索引2進行預先排序,然後再與'groupby'一起使用 –

+0

有沒有辦法在排序列表中取出最低的2個排序值你不需要檢查每個值? –

+0

@MikeElJackson我不知道我明白你在問什麼。你的意思是從原始輸入(=='(3,4,1.0)'除外)只考慮'(0,4,1.0),(1,4,1.0)'?也許你可以稍微更新一下原始問題來提供一個例子。 – niemmi

0

我不會在一個做到這一點雖然我相信這是可能的。

我首先做一個列表,每個值在指數2

values_at_index_2 = {t[2] for t in data} 
groups_by_value = [[t for t in data if t[2] == v] for v in values_at_index_2] 

然後拿起一個元組,每個組:

import random 
new_data = [random.choice(group) for group in groups_by_value]