0

I have a list like this:

l=[['a','b'],['c','d'],['a','b','c']....]

I want this to be converted as dictionary of following format:

[{
            'data': {'id': 'one', 'label': 'a'},

        },
        {
            'data': {'id': 'two', 'label': 'b'},

        },
{
            'data': {'id': 'three', 'label': 'c'},

        },
        {
            'data': {'id': 'four', 'label': 'd'},

        }]

I have tried the following code initially:

dict_list = { i : len(l) for i in l }

I got the following error:

TypeError: unhashable type: 'list'
Sri Test
  • 389
  • 1
  • 4
  • 21
  • You can not use lists (`i`) as keys in a dictionary, since, like the error says, these are not hashable. – Willem Van Onsem Jan 12 '20 at 15:36
  • Can you tell us more specifically how you want to map the nested list to the dictionary? – Sam Chats Jan 12 '20 at 15:41
  • @SamChats The same I have shown in the question.I want a nested key value pairs – Sri Test Jan 12 '20 at 16:27
  • You should try to create the dictionary in python directly like you need it for cytoscape. Instead of converting the array, that would save time and effort. Python has dictionaries, so that shouldn't be a problem. – Stephan T. Jan 13 '20 at 06:48
  • @StephanT. But I want the list to be converted into this dictionary format.I have lot many elements in list.How do I do it? – Sri Test Jan 13 '20 at 10:44
  • You would have to filter out all uniqe elements and put them into the cytoscape nodes array. For the edges, you would need to iterate over every element of the outer array and put these relations into the cytoscape edges array. Doing these things is not that impossible, but you would save a lot of time if you create the array the right way in the first place. – Stephan T. Jan 14 '20 at 06:59
  • Additionally, how are the edges supposed to be calculated? [a,b] and [a,b,c] seems quite strange to me. I got the node calculation down, but the edges are not clear enough. – Stephan T. Jan 14 '20 at 07:25
  • Also: It would be much easier, if the ids weren't written numbers but like this: **id: "n1",** or **id: "node1",**. Then, the question below wouldn't have the need for inflect. Is there a specific reason for the whole "one", "two" numbering? – Stephan T. Jan 17 '20 at 08:35

1 Answers1

2

The error you are getting is due to the fact you are trying to set a list as a dictionary key. The following example will reproducer the same results:

>>> d = dict()
>>> d[['a', 'b']] = 123
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    d[['a', 'b']] = 123
TypeError: unhashable type: 'list'

Let say it would work, it wouldn't create the expected list you wish to get. It would results with something like this:

{ ['a','b']: 2, 
  ['c','d']: 2, 
  ['a','b','c']: 3
}

In order to get the list you are wishing for you need to create a nested loop (native solution).

import inflect
p = inflect.engine()

l=[['a','b'],['c','d'],['a','b','c']]
new_list = list()
count = 1
already_used_labels = set()

# The nested loop...
for inner_list in l:
    for label in inner_list:
        if label in already_used_labels:
            continue
        new_list.append({'data': {'id': p.number_to_words(count), 'label': label}})
        count += 1
        already_used_labels.add(label)

This will results with:

[
 {'data': {'id': 'one', 'label': 'a'}}, 
 {'data': {'id': 'two', 'label': 'b'}},
 {'data': {'id': 'three', 'label': 'c'}}, 
 {'data': {'id': 'four', 'label': 'd'}}
]

P.S

For more information about how to convert integers into words (inflect package).

Amiram
  • 1,227
  • 6
  • 14
  • The question doesn't really specify this, but cytoscape.js needs nodes (this is what your result is) and edges. Without the edges, the layout of the graphs wouldn't make any sense. Your answer is great, but it won't work with cytoscape.js probably. – Stephan T. Jan 15 '20 at 09:46
  • 1
    @Sri-Test, please add more details to the question as @ Stephan-T pointed out. This way I could edit my answer so it will be more suitable for your problem. – Amiram Jan 15 '20 at 10:09
  • @Amiram This is really helpful.but as Stephan T. already mentioned.I need the nodes in each list to be connected.So,I need an other key in dictionary for edges like 'data': {'source': 'one', 'target': 'two'} .For better idea,please refer to this link – Sri Test Jan 17 '20 at 19:06
  • Can you please add an expected output example? – Amiram Jan 17 '20 at 20:13