0

I have looked at these already, but no luck so far stackquestion1 stackquestion2 stackquestion3 and many many others. It always seems to be different?

I really think it is a simple solution, but I have been trying for hours now. I want to get the values of a nested dictionary, within a for loop. I have a simplified example here:

def write_to_file(class_set, clusterdict, outfile):
with open(outfile, "w") as outputfile:
    writer = csv.writer(outputfile, delimiter='\t')
    class_list = list(class_set)
    header = ["\t"] + class_list
    writer.writerow(header)  # write header
    for organism, cluster in clusterdict.items():
        #print clusterdict.get(organism) # works, just to see if it does anything
        line = []
        #some stuff here that works, writing specific lines
        #part that doesnt work
        line.append(clusterdict.get(organism).get(cluster)) # gives TypeError: unhashable type: 'dict'
        line.append(clusterdict.get(organism) # does work, but of course gives me the wrong dict values
        writer.writerow(line)

The dict looks like this. Its a dictionary with multiple organisms and withing that a dictionary with multiple clusters. So each organism has multiple clusters, with (sometimes multiple) sets as values (I think the problem might be the sets?)

clusterdict = 
'organism1':{'cluster1': [set(['value1', 'value2']) , [set(['value3', 'value4'])], 'cluster2: [set(['value5', 'value6']) , [set(['value7', 'value8'])]} , 
'organism2':{.......} , 
'organism3':{.......} , etc

I tried many many ways to get the values. For example like dict[key1][key2], but this also gives me the "unhashable" error. Can someone give me some directions?

Fini
  • 163
  • 10
  • Your variable ``cluster`` **is** the dictionary. You are trying to use it as a key. If you want to iterate over the keys and values of ``cluster``, just do what you did with ``clusterdict`` ( -> ``for key, value in cluster.items():`` ). Side note: Why are you converting a list to a set to a list? sets are unordered data structure, they will likely change the order of your list items. You should consider to provide a [mcve] and you should also list the expected output in your question. – Mike Scotty Feb 27 '19 at 10:34
  • I thought that my "clusterdict" is my dictionary and I use for key,value in clusterdict.items(), but i named them organism and cluster instead of key and value – Fini Feb 27 '19 at 10:38
  • ``clusterdict`` is a dictionary, and it contains values that are also dictionaries. That's totally valid. – Mike Scotty Feb 27 '19 at 10:39
  • but then "organism" is also a dictionary? but that one does work – Fini Feb 27 '19 at 10:40
  • Nope, ``organism1`` is a key, and in this case your key is a string. Only the **value** associated with the key is a dictionary in this case. Keys have to be hashable, that's why your interpreter is complaining when you tried to use your ``cluster`` dictionary as a key. But then again, you don't want to use ``cluster`` as a key, because ``cluster`` is your **value**, just that your value is also a dict with keys and values. – Mike Scotty Feb 27 '19 at 10:41
  • so basically I have to make another for loop, to dissect the two dictionaries and then get the values from there? – Fini Feb 27 '19 at 10:43
  • 1
    Exactly ;) ``for key, value in cluster.items()`` – Mike Scotty Feb 27 '19 at 10:43
  • If you make it an answer I can mark it as solved? – Fini Feb 27 '19 at 10:44

1 Answers1

1

You are trying to use cluster as a key, but actually cluster is your value, and it's also a dictionary.

You can iterate over cluster just as you did with your main dictionary:

for organism, cluster in clusterdict.items():
    for key, value in cluster.items():
        ...

They error TypeError: unhashable type: 'dict' came from the fact that keys have to be hashable, and cluster is a dictionary - which is not hashable.

But then again, you don't want to use cluster as a key, because cluster is your value, just that your value is also a dict with keys and values.

Mike Scotty
  • 10,530
  • 5
  • 38
  • 50