简体   繁体   中英

Best way to reverse a dictionary with list as values?

I currently have a dictionary like so:

app_dict = {test1 : [[u'app-1', u'app-2', u'app-3', u'app-4']]}

I have a function that reverses the dictionary (which is proven to be working with another dictionary).

def reverse_dictionary(self, app_dict):
    """ In order to search by value, reversing the dictionary """
    return dict( (v,k) for k in app_dict for v in app_dict[k] )

I get an error when I do the following:

data = reverse_dictionary(app_dict)
print data

ERROR:
return dict( (v,k) for k in app_dict for v in app_dict[k] )
TypeError: unhashable type: 'list'

I'm not sure, but I think the issue is with how my dictionary is structured, I'm not sure why there are double brackets on my list, and I can't seem to remove them. How can I modify reverse_dictionary function to work with app_dict?

EDIT:

new_dict = collections.defaultdict(list)
app_dict = collections.defaultdict(list)

#at this point, we have filled app_dict with data (cannot paste here)
for o, q in app_dict.items():
    if q[0]:
        new_dict[o].append(q[0])

Note that when I print new_dict at this point, my dictionary values show in the following format (with double brackets): [[u'app-1', u'app-2', u'app-3', u'app-4']]

If I change the append line to: new_dict[o].append(q[0][0]) Which I assume would strip the outter brackets, instead of this, it ONLY appends the first value in the list:

[u'app-1']

I believe this is the issue I'm having is I am not able to successfully strip the outter brackets from the list.

The error is simply saying that lists cannot be used as a key in a dictionary because they are mutable. However, tuples are immutable and therefore can be used as a key.

A possible work around could be:

def reverse_dictionary(self, app_dict):
    """ In order to search by value, reversing the dictionary """
    return dict( (v,k) if type(v) != list else (tuple(v), k) for k in app_dict for v in app_dict[k])

If I use your edit, this might work

new_dict = collections.defaultdict(list)
app_dict = collections.defaultdict(list)

#at this point, we have filled app_dict with data (cannot paste here)
for o, q in app_dict.items():
    if q[0]:
        for value in q[0]:
            new_dict[o].append(value)

This is the same reverse function as the one you have but takes into account that the dictionary contains a list of lists on which only the first element is used. I believe that the data is not in the right format and hence the double brackets, but with this modification it works.

>>> dict([(v, k) for k in app_dict for v in app_dict[k][0]])
{u'app-4': 'test1', u'app-3': 'test1', u'app-2': 'test1', u'app-1': 'test1'}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM