2017-12-08 13 views
0

タプルの中にキーと値のペアのリストがあり、それらのタプルのうちの1つだけが異なる値を含むことが知られています。キーはすべて異なっている。例えば、タプルのリスト内で単一の一意の値を見つける

pairs = [ 
     ('John', 101991), 
     ('Bob', 101991), 
     ('Tom', 101997), 
     ('Larry', 101991), 
     ('Howard', 101991) 
     ] 

は、私は別の値を持つタプルの鍵を特定する必要があります。この値が他の値より大きいか小さいかはわかりません。

どうすればこの問題を解決できますか?

+0

何か試しましたか? – haifzhan

答えて

2

あなたはitertools.groupbyを使用することができます。

import itertools 
pairs = [ 
    ('John', 101991), 
    ('Bob', 101991), 
    ('Tom', 101997), 
    ('Larry', 101991), 
    ('Howard', 101991) 
    ] 
new_pairs = [(a, list(b)) for a, b in itertools.groupby(sorted(pairs, key=lambda x:x[-1]), key=lambda x:x[-1])] 
new_val = [a for a, b in new_pairs if len(b) == 1] 

出力:

[101997] 

編集:より効率的なソリューションの辞書を使用して:

from collections import defaultdict 
d = defaultdict(list) 
for a, b in pairs: 
    d[b].append(a) 

new_val = [a for a, b in d.items() if len(b) == 1] 
+0

これはO(nlogN)です。辞書を使って、これをO(N)にすることができます。大きな入力については、これは重要です。 –

+0

@MartijnPieters良い点。私の最近の編集を見てください。 – Ajax1234

+0

名前を保存する理由は何ですか?あなたは数えたい、リストしたくない。 'd =カウンタ(new_pairsのbまたはa、b)'、 '[bの場合はb、count == 1の場合はd.items()でカウントする]'。 –

1

または代わり

pairs = [ 
     ('John', 101991), 
     ('Bob', 101991), 
     ('Tom', 101997), 
     ('Larry', 101991), 
     ('Howard', 101991) 
] 

stat = {} 
for k, v in pairs: 
    if not v in stat: stat[v] = [] 
    stat[v].append((k, v)) 

for v in stat: 
    if len(stat[v]) == 1: 
     print(stat[v][0][0]) #prints the key 'Tom' 
1

私は、別途解凍するだけキーのリストと値のリストを選ぶと思います:

keys, vals = zip(*pairs) 

その後、私はnumpyのをそれぞれのユニークな値の数をカウントしたい:

unique, counts = np.unique(vals, return_counts=True) 

そして、あなたがしたい値が最小カウントのいずれかになります。

myminval = unique[np.argmin(counts)] 

次に、あなたがあなたのリスト0にこの値を見つけますfキー:

keys[vals.index(myminval)] 
関連する問題