2017-02-01 57 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]