根据元组中的索引删除重复的元组值

Mik*_*son 2 python random tuples list duplicates

有没有办法根据元组中的索引删除重复的元组.说我有

[(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)]
Run Code Online (Sandbox Code Playgroud)

我可以随机保留一个元组,其中每个副本在索引2处具有相同的值吗?

因此,有3个元组在索引2处具有值1.0,两个元组在索引2处具有值2.0,一个在索引2处具有值3,依此类推.

因此,(0,4,1.0)可以从索引2处的值1.0中随机选择,并且(1,3,2.0)可以从索引2处的值2.0中随机选择.说,(1,2,3.0)是从索引2处的值3.0中随机选择.然后,我的列表看起来像

[(0, 4, 1.0),(1, 3, 2.0), (1, 2, 3.0), (2, 4, 4.0), (2, 3, 5.0), (0, 1, inf)]
Run Code Online (Sandbox Code Playgroud)

我从来没有遇到过这样或者至少有效的功能.

nie*_*mmi 5

您可以使用itertools.groupby基于索引2处的值对元组进行分组.然后,对于每个组,您可以使用它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)]
Run Code Online (Sandbox Code Playgroud)

在上面groupby返回可迭代(key, group)元组,其中key是由给定的第二个参数返回的值groupby,group是组中元素的可迭代:

>>> [(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),))]
Run Code Online (Sandbox Code Playgroud)

由于我们不需要密钥,我们可以将其丢弃并将组转换为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)]
Run Code Online (Sandbox Code Playgroud)

请注意,上面预期索引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)]
Run Code Online (Sandbox Code Playgroud)