mandosoft
mandosoft

Reputation: 183

Python alternative to using List as Dictionary Key?

I currently have a dictionary that maps normalized mutual information scores to aligned sites in a multiple sequence alignment, which are stored in a list. However, I've realized that two list may happen to have the same score. Thus only one list will be stored in the dictionary since the score is the key. Clusters should be unique though, so I'm not sure what to do since a my list doesn't have a hash function.

This is what my data looks like. Ideally I would simply like to reverse the keys and values.

{
0.475: [10, 11]
0.434: [12, 14]
0.404: [16, 18]
0.341: [21, 22]
}

Upvotes: 0

Views: 1190

Answers (4)

metageni
metageni

Reputation: 11

Dictionary comprehension should do it with no problem.

my_dict = {0.475: [10, 11], 0.434: [12, 14], 0.404: [16, 18], 0.341: [21, 22]}

my_dict = {my_dict[k]:k for k in my_dict}

Note: if you want to have an if-statement inside of it, you are able to.

Upvotes: 0

mathfux
mathfux

Reputation: 5949

You can use comprehension of dictionary here:

d = {0.475: [10, 11], 0.434: [12, 14], 0.404: [16, 18], 0.341: [21, 22]}
print({tuple(d[n]):n for n in d})

Output

{(10, 11): 0.475, (12, 14): 0.434, (16, 18): 0.404, (21, 22): 0.341}

You can't reverse keys and values straightforwardly because lists are unhashable and therefore can't be kept as keys.

Update

In case you have duplicated lists, you might like to create enumeration of repeated lists. You can do it like this:

from collections import defaultdict
d = {0.475: [10, 11], 0.434: [12, 14], 0.404: [16, 18], 0.341: [12, 14]}
new_d = dict()
d_counts = defaultdict(int)
for n in d.keys():
    value = tuple(d[n])
    new_d[(value, d_counts[value])] = n
    d_counts[value] += 1
print(new_d)

Output2

{((10, 11), 0): 0.475, ((12, 14), 0): 0.434, ((16, 18), 0): 0.404, ((12, 14), 1): 0.341}

Upvotes: 2

tbrk
tbrk

Reputation: 156

mydict = {0.475: [10, 11],
          0.434: [12, 14],
          0.404: [16, 18],
          0.341: [21, 22]}

newdict = dict()

for k, v in mydict.items():
    newdict[tuple(v)] = k

print(newdict)
# {(10, 11): 0.475, (12, 14): 0.434, (16, 18): 0.404, (21, 22): 0.341}

Upvotes: 1

Gocht
Gocht

Reputation: 10256

From this answer, you could try to create a new class from built-in dict:

class Dictlist(dict):
    def __setitem__(self, key, value):
        try:
            self[key]
        except KeyError:
            super(Dictlist, self).__setitem__(key, [])
        self[key].append(value)

So...

>>> d = Dictlist()
>>> d['100'] = [1, 2]
>>> d['100'] = [3, 4]
>>> d
{'100': [[1, 2], [3, 4]]}

Upvotes: 0

Related Questions