Reputation: 23
I have a dict with tuple keys as below
{('age', 'Low', 'Pos') : 3 ,
('age', 'High', 'Pos') : 11 ,
('age', 'Low', 'Neg') : 8 ,
('age', 'High', 'Neg') : 8 ,
('sex', 'male', 'Pos') : 13 ,
('sex', 'female', 'Pos') : 1 ,
('sex', 'male', 'Neg') : 10 ,
('sex', 'female', 'Neg') : 6}
Now I want to get keys which are the same in index 0,1
e.g:
('sex', 'female', 'Pos') , ('sex', 'female', 'Neg')
or
('age', 'Low', 'Pos') , ('age', 'Low', 'Neg')
How can I do this in python?
This is what I currently have:
x = [i for i in d.keys() if i[0]=='age' and i[1]=='Low']
Upvotes: 0
Views: 3008
Reputation: 4343
A simple approach:
x = [[k for k in d.keys() if k[:2] == s] for s in set(k[:2] for k in d.keys())]
This will group your keys in lists with the same first two elements.
Upvotes: 0
Reputation: 2121
I don't think this is the best data structure for the types of manipulations you want to do (I think a nested dictionary would make more sense). Nonetheless, assuming you have a good reason to store it in this way one solution to use a groupby
on index 0 and 1 as such:
from itertools import groupby
data = {('age', 'Low', 'Pos') : 3 ,
('age', 'High', 'Pos') : 11 ,
('age', 'Low', 'Neg') : 8 ,
('age', 'High', 'Neg') : 8 ,
('sex', 'male', 'Pos') : 13 ,
('sex', 'female', 'Pos') : 1 ,
('sex', 'male', 'Neg') : 10 ,
('sex', 'female', 'Neg') : 6}
sorted_keys = sorted(data.keys())
index_groups = {k: list(m) for k, m in groupby(sorted_keys, lambda x: x[:2]}
# index_groups is a dict of list with all keys grouped by index 0, 1
Upvotes: 2
Reputation: 27311
You can slice the keys to get the first two indexes, and use a defaultdict to collect them:
from collections import defaultdict
data = {
('age', 'Low', 'Pos') : 3 ,
('age', 'High', 'Pos') : 11 ,
('age', 'Low', 'Neg') : 8 ,
('age', 'High', 'Neg') : 8 ,
('sex', 'male', 'Pos') : 13 ,
('sex', 'female', 'Pos') : 1 ,
('sex', 'male', 'Neg') : 10 ,
('sex', 'female', 'Neg') : 6
}
prefix2 = defaultdict(list)
for tuple_key in data:
prefix2[tuple_key[:2]].append(tuple_key)
# jump through some hoops to get pretty output
import pprint
print pprint.pprint(dict(prefix2)) # converts back to regular dict since pprint likes them better
the output from the above is:
{('age', 'High'): [('age', 'High', 'Neg'), ('age', 'High', 'Pos')],
('age', 'Low'): [('age', 'Low', 'Pos'), ('age', 'Low', 'Neg')],
('sex', 'female'): [('sex', 'female', 'Pos'), ('sex', 'female', 'Neg')],
('sex', 'male'): [('sex', 'male', 'Pos'), ('sex', 'male', 'Neg')]}
Upvotes: 1