Mustafa Iqbal
Mustafa Iqbal

Reputation: 155

Finding all keys of a multi-key dictionary based on one key

I have a dictionary in which 3 keys are assigned to each value: dictTest[c,pH,T] = value. I would like to retrieve all values corresponding to a given, single key: dictTest[c,*,*] = value(s)

I looked online but could not find any solutions in Python, only C#. I've tried using dictTest[c,*,*] but get a syntax error. Another option I can see is using multi-level keys, i.e. have the first level as c, second as pH and so on, i.e. dictTest[c][pH][T] = value (from http://python.omics.wiki/data-structures/dictionary/multiple-keys)

Here is some test code:

dictTest={}
dictTest[1,100,10]=10
dictTest[1,101,11]=11

The following gives a syntax error:

print(dictTest[1,*,*])

Whilst trying to specify only one key gives a key error:

print(dictTest[1])

I've also tried the above mentioned multi-level keys, but it raises a syntax error when I try and define the dictionary:

dictTest[1][100][10]=10

In the above example, I would like to specify only the first key, (i.e. key1=1, and return both values of the dictionary, as the first key value of both is 1.

Thanks, Mustafa.

Upvotes: 2

Views: 1480

Answers (4)

ymochurad
ymochurad

Reputation: 999

Another option to implement is:

from collections import defaultdict

dictTest = defaultdict(lambda: defaultdict(dict))
dictTest[1][100][10] = 10
dictTest[1][101][11] = 11

print(dict(dictTest[1]))

The output is:

{100: {10: 10}, 101: {11: 11}}

Upvotes: 1

Maurice Meyer
Maurice Meyer

Reputation: 18106

To create a multi level nested dictionary, you can use of recursivly created defaultdicts:

from collections import defaultdict


def recursive_defaultdict():
    return defaultdict(recursive_defaultdict)

dictTest = recursive_defaultdict()
dictTest[1][100][10] = 10
dictTest[1][101][11] = 11

print(dictTest[1][100])

Output:

defaultdict(<function recursive_defaultdict at 0x1061fe848>, {10: 10})

Upvotes: 1

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140168

The key of your dictionary is a tuple of 3 values. It's not a "multi-key" dict that you can search efficiently based on one of the element of the tuple.

You could perform a linear search based on the first key OR you could create another dictionary with the first key only, which would be much more efficient if the access is repeated.

Since the key repeats, you need a list as value. For instance, let the value be a tuple containing the rest of the key and the current value. Like this:

dictTest={}
dictTest[1,100,10]=10
dictTest[1,101,11]=11
dictTest[2,101,11]=30

import collections

newdict = collections.defaultdict(list)

for (newkey,v2,v3),value in dictTest.items():
    newdict[newkey].append(((v2,v3),value))

now newdict[1] is [((101, 11), 11), ((100, 10), 10)] (the list of all values matching this key, with - added - the rest of the original key so no data is lost)

and the whole dict:

>>> dict(newdict)
{1: [((101, 11), 11), ((100, 10), 10)], 2: [((101, 11), 30)]}

Upvotes: 1

mathew gunther
mathew gunther

Reputation: 180

dictTest={}
dictTest[1,100,10]=10
dictTest[1,101,11]=11
dictTest[2,102,11]=12

print([dictTest[i] for i in dictTest.keys() if i[0]==1])
print([dictTest[i] for i in dictTest if i[0]==1])            #more pythonic way

#creating a function instead of printing directly
def get_first(my_dict,val):
    return [my_dict[i] for i in my_dict if i[0]==val]

print(get_first(dictTest,1))

Upvotes: 1

Related Questions