S Roshan
S Roshan

Reputation: 23

get items from a dict with tuple keys in python

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

Answers (3)

Tarifazo
Tarifazo

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

nico
nico

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

thebjorn
thebjorn

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

Related Questions