Tim
Tim

Reputation: 2843

Find single unique value in list of tuples

I have a list of key-value pairs in tuples, and it's known that one (and only one) of those tuples will contain a different value. The keys are all different. For example,

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

I need to identify the key of the tuple with the different value. It is not known whether this value will be larger or smaller than the others.

How can I accomplish this?

Upvotes: 0

Views: 92

Answers (3)

Ajax1234
Ajax1234

Reputation: 71471

You can use 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]

Output:

[101997]

Edit: more efficient solution using dictionaries:

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]

Upvotes: 2

n3utrino
n3utrino

Reputation: 1210

I'd pick out just a list of the keys and a list of the values separately by unzipping:

keys, vals = zip(*pairs)

Then I'd count the number of each unique value with numpy:

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

And the value you want is the one with the smallest counts:

myminval = unique[np.argmin(counts)]

Then you find this value in your list of keys:

keys[vals.index(myminval)]

Upvotes: 1

ewcz
ewcz

Reputation: 13097

or alternatively

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'

Upvotes: 1

Related Questions