0

While running the below NetworkX python 3.5 code (within Jupyter) I get an error that I don't really understand. Any help is greatly appreciated.

import pandas as pd
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import os, warnings     
warnings.filterwarnings('ignore')
%matplotlib inline
%config InlineBackend.figure_format = 'retina'


## NODES

a = [ (  'a_%d' % i, {'a' : i}) for i in range(0,5) ]
b = [ (  'b_%d' % i, {'b' : i}) for i in range(0,5) ]
c = [ (  'c_%d' % i, {'c' : i}) for i in range(0,5) ]
d = [ (  'd_%d' % i, {'d' : i}) for i in range(0,5) ]

E = [ (  'E_%d' % h, {'a': i}, {'b': j}, {'c': k}, {'d': l} )
        for h in range(1,626) for i in range(0,5) 
        for j in range(0,5) for k in range(0,5) 
        for l in range(0,5) ]

## GRAPH initialization

testgraph = nx.Graph()
list_of_nodegroups = [a, b, c , d, E]

And this is where it fails:

## GRAPH construction - adding nodes

for ng1 in list_of_nodegroups1:
    testgraph.add_nodes_from(ng1)

I get this error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.5/dist-packages/networkx/classes/graph.py in add_nodes_from(self, nodes_for_adding, **attr)
    535             try:
--> 536                 if n not in self._node:
    537                     self._adj[n] = self.adjlist_inner_dict_factory()

TypeError: unhashable type: 'dict'

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-10-718f064c86a3> in <module>()
      1 for ng1 in list_of_nodegroups:
----> 2     testgraph.add_nodes_from(ng1)

/usr/local/lib/python3.5/dist-packages/networkx/classes/graph.py in add_nodes_from(self, nodes_for_adding, **attr)
    540                     self._node[n].update(attr)
    541             except TypeError:
--> 542                 nn, ndict = n
    543                 if nn not in self._node:
    544                     self._adj[nn] = self.adjlist_inner_dict_factory()

    ValueError: too many values to unpack (expected 2)

Referring to (as I understand it) 2 things:

  • "unhashable type: 'dict'"
  • "ValueError: too many values to unpack (expected 2)"

I am trying to figure out how exactly this could be solved, whether within this code or elsewhere, and any help is much appreciated!

EDIT:

My objective is to have a graph consisting of 4 types of 'children-nodes' being a,b,c,d and 1 type of 'mother-nodes' being E, like this:

[ ('E1', {'a0': 0, 'b0': 0, 'c0': 0, 'd0': 0} ),
  ('E2', {'a1': 1, 'b0': 0, 'c0': 0, 'd0': 0} ),
  ('E3', {'a1': 1, 'b1': 1, 'c0': 0, 'd0': 0} ),
   ...
  ('E625', {'a5': 5, 'b5': 5, 'c5': 5, 'd5': 5} ),
]

1 Answer 1

1

Documentation for Graph.add_nodes_from(nodes_for_adding, **attr): nodes_for_adding (iterable container) – A container of nodes (list, dict, set, etc.). OR A container of (node, attribute dict) tuples. Node attributes are updated using the attribute dict.

Each element in your list E is a tuple containing one node and 4 dicts, while add_nodes_from only accepts a single dict. Those 4 dicts should be merged into a single dict: {'a': i, 'b': j, 'c': k, 'd': l}.

Also, the list E has 625 × 5⁴ = 390625 elements. Is this your intention, or you are trying to enumerate the node? If you want to enumerate, it does not work as you expected. Instead, use

from itertools import product

E = [('E_%d' % h, {'a': i, 'b': j, 'c': k, 'd': l})
     for h, (i, j, k, l) in enumerate(product(range(5), repeat=4), start=1)]
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @ducminh You're right about the dicts having to be one (not 4 separate, I overlooked that. My only goal is to have 4 sub-types of nodes, each with n variation (5 in this example). And a 5th 'mother'-type that stores all possible combinations between them: 5^4 625. But I might have noted that down incorrectly.
If you are using for h in ... for i in ... that way, it will produce a list of 390625 elements, but only 625 nodes will be added. For example, there will be two tuples ('E1', {...}) and ('E1', {...}), and the first node produced by the first tuple will be overwritten by the second tuple. You can try with smaller values to see the effect.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.