Reputation: 2843
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
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
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
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