One problem is arising from the fact that (1)
and (20)
are not tuples (as pointed out by Ilja Everilä in the comments). Since they are actually of type int
, you can not iterate over them or use []
to index.
First a note about enumerate()
, which you were using incorrectly. This function returns a tuple of (index, value)
. More info here.
If changing the source data is not an option, you can modify your code a little to get the desired result. Loop over the tuples as before, but use isinstance
to check if the element is an int
.
graph = {}
for i, x in enumerate(o):
graph[x] = {}
if isinstance(n[i], int):
graph[x][n[i]] = c[i]
else:
for j in range(len(n[i])):
graph[x][n[i][j]] = c[i][j]
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}
This else
block of this code can be simplified further, using zip()
:
graph = {}
for i, x in enumerate(o):
graph[x] = {}
if isinstance(n[i], int):
graph[x][n[i]] = c[i]
else:
for y, z in zip(n[i], c[i]):
graph[x][y] = z
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}
However, the better solution is to change the source data n
and c
to contain only tuples:
def make_tuple(x):
return x if isinstance(x, tuple) else (x, )
new_n = map(make_tuple, n)
new_c = map(make_tuple, c)
Then the code above no longer needs the isinstance()
check, and can be simplified to:
graph = {}
for i, x in enumerate(o):
graph[x] = {}
for y, z in zip(new_n[i], new_c[i]):
graph[x][y] = z
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}
We can simplify further into:
graph = {}
for ko, N, C in zip(o, new_n, new_c):
graph[ko] = {}
for kn, vc in zip(N, C):
graph[ko][kn] = vc
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}
Or if to the compact one liner (direct translation of the code block above to dict comprehension):
graph = {ko: {kn:vc for kn, vc in zip(N, C)} for ko, N, C in zip(o, new_n, new_c)}
print graph
#{0: {1: 30, 2: 70}, 1: {1: 20}}