2017-02-01 7 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の各重複値が同じ値を持つタプルをランダムに1つ保持できますか?

したがって、インデックス2に値1.0を持つ3つのタプル、インデックス2に値2.0を持つ2つのタプル、インデックス2に値3を持つタプルなどがあります。

したがって、インデックス2の値1.0からランダムに(0、4,1.0)が選択され、インデックス2の値2.0からランダムに選択される可能性があります。 (1、 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)] 

ようになり、2 そして、インデックスの値3.0から選ばれました。

あなたはタプルを選択する random.choiceを使用することができ、各グループのために、インデックス2の値に基づいてグループにタプルを itertools.groupbyを使用することができ
+0

は、インデックス2で同じ値を持つすべてのタプルです入力の中でお互いに隣に?出力の正しい順序は何ですか? – niemmi

+0

私は、彼らが –

答えて

4

>>> 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が期待その配列する:上記インデックス2で同じ値を持つタプルが入力で互いに隣接していることを期待

>>> [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)] 

注意。そうでない場合は、それに応じて元のリストをソートしてからgroupbyに渡すことができます。

更新あなただけではなく、リスト内包のジェネレータ式を使用してisliceとそこから値を引き出すことができ、結果の最初の3つの値をしたい場合:

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

私は1つでこれをしないだろう私はそれが可能であると確信しています。

私は、最初のインデックス2で値ごとに1つのリストになるだろう。そして、各グループに1組を選ぶ

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] 
関連する問題