Create a networkX graph from nested python dictionary - python

I created a nested dictionary from a data
dataset =
0 1 2
0 2 3
0 3 6
0 7 8
1 4 7
1 2 5
2 5 4
2 11 5
3 6 2
3 11 4
5 8 3
6 9 3
9 10 6
The python code is
data = np.array(dataset).tolist()
graph = collections.defaultdict(list)
for row in data:
graph[row[0]].append({row[1]: row[2]})
graph[row[1]].append({row[0]: row[2]})
wt = dict(graph)
print(dict(graph))
`This code generates
data_dict = {0: [{1: 2}, {2: 3}, {3: 6}, {7: 8}], 1: [{0: 2}, {4: 7}, {2: 5}], 2: [{0: 3}, {1: 5}, {5: 4}, {11: 5}],
3: [{0: 6}, {6: 2}, {11: 4}], 4: [{1: 7}], 5: [{2: 4}, {8: 3}], 6: [{3: 2}, {9: 3}], 7: [{0: 8}], 8: [{5: 3}], 9: [{6: 3}, {10: 6}],
10: [{9: 6}], 11: [{2: 5}, {3: 4}]}
The output from my algorithm results is (nodes and their corresponding adjacent list)
for node in adj_list:
print node , adj_list[node]
11 [{'0': 5}]
10 [{'9': 6}]
0 [{'4': 7}, {'11': 5}, {'5': 4}, {'6': 2}]
5 [{'8': 3}, {'0': 4}]
4 [{'0': 7}]
6 [{'9': 5}, {'0': 2}]
9 [{'6': 5}, {'10': 6}]
8 [{'5': 3}]
I need to create a networkX graph from the output results. Any help Please

Related

i want to create a dictionary of list of dictionaries

i want to create a dictionary of an array of dictionaries from a list of node pairs and their weight.
nets = pd.read_table('data/nodes.txt', header = None)
bb = np.array(nets).tolist()
graph = collections.defaultdict(dict)
for row in bb:
graph[row[0]][row[1]]=row[2]
graph[row[1]][row[0]] = row[2]
print(dict(graph))
which resulted in this dictionary
{0: {1: 2, 2: 3, 3: 6, 7: 8}, 1: {0: 2, 2: 5, 4: 7}, 2: {0: 3, 1: 5, 11: 5, `5: 4}, 3: {0: 6, 11: 4, 6: 2}, 4: {1: 7}, 5: {8: 3, 2: 4}, 6: {9: 3, 3: 2}, 7: {0: 8}, 8: {5: 3}, 9: {10: 6, 6: 3}, 10: {9: 6}, 11: {2: 5, 3: 4}}`
and want a it in this form.
{0: [{1: 2}, {2: 3}, {3: 6}, {7: 8}],
1: [{0: 2}, {2: 5}, {4: 7}],
2: [{0: 3}, {1: 5}, {11: 5}, {5: 4}],
3: [{0: 6}, {11: 4}, {6: 2}],
4: [{1: 7}],
5: [{8: 3}, {2: 4}],
6: [{9: 3}, {3: 2}],
7: [{0: 8}, 8: {5: 3}],
9: [{10: 6}, {6: 3}],
10: [{9: 6}],
11: [{2: 5}, {3: 4}]}
You can do this pretty easily if you really want to, though I'd look carefully at where you're going to use this data structure to see if your existing more logical structure could be made to work instead.
Anyway, here's a quick implementation that should do what you want:
graph = collections.defaultdict(list)
for row in bb:
graph[row[0]].append({row[1]: row[2]})
graph[row[1]].append({row[0]: row[2]})

Separate list elements by theirs property in Python

I have list p1:
p1 = [
{'id': 1, 'area': 5},
{'id': 2, 'area': 6},
{'id': 3, 'area': 10},
{'id': 4, 'area': 6},
{'id': 5, 'area': 6},
{'id': 6, 'area': 6},
{'id': 7, 'area': 4},
{'id': 8, 'area': 4}
]
And I need to separate this list by area value, like this (p2):
p2 = {
4: [
{'id': 7, 'area': 4},
{'id': 8, 'area': 4}
],
5: [
{'id': 1, 'area': 5}
],
6: [
{'id': 2, 'area': 6},
{'id': 4, 'area': 6},
{'id': 5, 'area': 6},
{'id': 6, 'area': 6}
],
10: [
{'id': 3, 'area': 10}
]
}
My solution is:
areas = {x['area'] for x in p1}
p2 = {}
for area in areas:
p2[area] = [x for x in p1 if x['area'] == area]
It seems to work, but is there any better and more "pythonic" solution?
Using groupby you get
>>> import itertools
>>> f = lambda t: t['area']
>>> {i: list(b) for i, b in itertools.groupby(sorted(p1, key=f), key=f)}
Gives
{4: [{'area': 4, 'id': 7},
{'area': 4, 'id': 8}],
5: [{'area': 5, 'id': 1}],
6: [{'area': 6, 'id': 2},
{'area': 6, 'id': 4},
{'area': 6, 'id': 5},
{'area': 6, 'id': 6}],
10: [{'area': 10, 'id': 3}]}
edit: If you don't like using lambdas you can also do, as suggested by bro-grammer
>>> import operator
>>> f = operator.itemgetter('area')
You can simply use defaultdict:
from collections import defaultdict
result = defaultdict(list)
for i in p1:
result[i['area']].append(i)
Yes, use one of the grouping idioms. Using a vanilla dict:
In [15]: p1 = [
...: {'id': 1, 'area': 5},
...: {'id': 2, 'area': 6},
...: {'id': 3, 'area': 10},
...: {'id': 4, 'area': 6},
...: {'id': 5, 'area': 6},
...: {'id': 6, 'area': 6},
...: {'id': 7, 'area': 4},
...: {'id': 8, 'area': 4}
...: ]
In [16]: p2 = {}
In [17]: for d in p1:
...: p2.setdefault(d['area'], []).append(d)
...:
In [18]: p2
Out[18]:
{4: [{'area': 4, 'id': 7}, {'area': 4, 'id': 8}],
5: [{'area': 5, 'id': 1}],
6: [{'area': 6, 'id': 2},
{'area': 6, 'id': 4},
{'area': 6, 'id': 5},
{'area': 6, 'id': 6}],
10: [{'area': 10, 'id': 3}]}
Or more neatly, using a defaultdict:
In [23]: from collections import defaultdict
In [24]: p2 = defaultdict(list)
In [25]: for d in p1:
...: p2[d['area']].append(d)
...:
In [26]: p2
Out[26]:
defaultdict(list,
{4: [{'area': 4, 'id': 7}, {'area': 4, 'id': 8}],
5: [{'area': 5, 'id': 1}],
6: [{'area': 6, 'id': 2},
{'area': 6, 'id': 4},
{'area': 6, 'id': 5},
{'area': 6, 'id': 6}],
10: [{'area': 10, 'id': 3}]})

[Python]How to order the value of json array

I got a json array like this
[{'n0': 16}, {'n2': 6}, {'n3': 1}, {'n4': 1}, {'n5': 11}, {'n6': 2}, {'n7': 6}]
How can i order this one depends on the value of nX?
Here you are:
def getkey(item):
return int(item.keys()[0][1:])
def compare(a,b):
k1,k2=getkey(a),getkey(b)
if k1 == k2 :
return 0
return -1 if k1 <k2 else 1
print l
l.sort(compare)
.. and the list is sorted.
use python sorted function with key
lst = [{'n0': 16}, {'n2': 6}, {'n3': 1}, {'n4': 1}, {'n5': 11}, {'n6': 2}, {'n7': 6}]
new_lst = sorted(lst, key=lambda x:x.values()[0])
# [{'n3': 1}, {'n4': 1}, {'n6': 2}, {'n2': 6}, {'n7': 6}, {'n5': 11}, {'n0': 16}]
if you want to sort the list in place without creating new list, use list sort method
lst = [{'n0': 16}, {'n2': 6}, {'n3': 1}, {'n4': 1}, {'n5': 11}, {'n6': 2}, {'n7': 6}]
lst.sort(key=lambda x:x.values()[0])
# [{'n3': 1}, {'n4': 1}, {'n6': 2}, {'n2': 6}, {'n7': 6}, {'n5': 11}, {'n0': 16}]

Reading from file into dictionaries, and strange eval() behaviour

Creating dictionaries from file using eval(), or ast.literal_eval() (as suggested by others) yields strange results, and I'm not sure why.
My file, file.txt contains this:
{0 : {1: 6, 1:8}, 1 : {1:11}, 2 : {3: 9}, 3 : {},4 : {5:3},5 : {2: 7, 3:4}}
I read it into a dictionary and print the contents out as such
graph1 = {}
graph1 = ast.literal_eval(open("file.txt").read())
and I get this thing, where the {1:6} is missing.
{0: {1: 8}, 1: {1: 11}, 2: {3: 9}, 3: {}, 4: {5: 3}, 5: {2: 7, 3: 4}}
I change the contents of 'file.txt' to this:
{0: {2: 7, 3: 4}, 1: {1: 11}, 2: {3: 9}, 3: {}, 4: {5: 3}, 5: {2: 7, 3: 4}}
And then the correct contents display!
Then I change the contents of file.txt to this, where I rewrite 1:6 as 2:6
{0 : {2: 6, 1:8}, 1 : {1:11}, 2 : {3: 9}, 3 : {},4 : {5:3},5 : {2: 7, 3:4}}
And this is the output, where {2:6} and {1:8} switch places!
{0: {1: 8, 2: 6}, 1: {1: 11}, 2: {3: 9}, 3: {}, 4: {5: 3}, 5: {2: 7, 3: 4}}
All I want to do is correctly read the contents of a file into my dictionary. What is going wrong?
Dictionaries can not have duplicate key. In case same key is provided to the dict object, former value is overridden by the later value.
For example:
>>> d = {'a': 'x', 'b': 'y', 'c': 'z', 'a': 'w'}
>>> d
{'a': 'w', 'c': 'z', 'b': 'y'} # ('a': 'x') is overridden by ('a': 'w')
The reason of missing 1:6 is because of that you have 1:8 in your dictionary too, and since python use hash table for implementing the dictionaries, they don't preserve duplicate keys (because they have same hash value) and the reason of changing the order is that dictionaries don't have a specific order because of the way they are implemented.

Merging two dictionaries of different sizes and different values

If I have two different dictionaries I have created from Queries of different sizes
dictionary1:
{'id': 1 , 'passCount': 3}, {'id': 2 , 'passCount': 4}, {'id': 5 , 'passCount': 7}, {'id': 6, 'passCount': 3}
dictionary2:
{'id': 1 , 'failCount': 1}, {'id': 3 , 'failCount': 2}, {'id': 5 , 'failCount': 3}
Originally, I created a master list from these two dictionaries:
List = []
for i in dictionary1:
for j in dictionary2:
if i['id'] = j['id]:
List.append[i['id'],i['passCount'],j['failCount']]
else:
List.append[i['id'],i['passCount'],0]
List.append[j['id'],0, j['failCount']
return List
When I would print this List out for my data, I would only get a List of id's that match, and would not take into account the other ones.
For that reason I want to print a dictionary where I could get it to print
{'id' = 1, 'passCount' = 3, 'failCount' = 1}, {'id': 2 , 'passCount': 4, 'failCount' = 0}... and so on without deleting any of the id's
Thanks
Short solution using dict.setdefault and dict.update methods:
l1 = [{'id': 1 , 'passCount': 3}, {'id': 2 , 'passCount': 4}, {'id': 5 , 'passCount': 7}, {'id': 6, 'passCount': 3}]
l2 = [{'id': 1 , 'failCount': 1}, {'id': 3 , 'failCount': 2}, {'id': 5 , 'failCount': 3}]
grouped = {}
for d in l1+l2:
grouped.setdefault(d['id'], {'failCount':0, 'passCount': 0}).update(d)
result = [d for d in grouped.values()]
print(result)
The output:
[{'passCount': 3, 'id': 1, 'failCount': 1}, {'passCount': 4, 'id': 2, 'failCount': 0}, {'passCount': 0, 'id': 3, 'failCount': 2}, {'passCount': 7, 'id': 5, 'failCount': 3}, {'passCount': 3, 'id': 6, 'failCount': 0}]
Maybe they're two different lists ,not dictionaries,so I assume they're two lists:
failCount set to 0 by default,you can try this:
a=[{'id': 1 , 'passCount': 3}, {'id': 2 , 'passCount': 4}, {'id': 5 , 'passCount': 7}, {'id': 6, 'passCount': 3}]
b=[{'id': 1 , 'failCount': 1}, {'id': 3 , 'failCount': 2}, {'id': 5 , 'failCount': 3}]
for j in a:
j.update({'failCount': 0})
for i in b:
if i["id"]==j["id"]:
j.update(i)
print(a)
Output:
[{'id': 1, 'passCount': 3, 'failCount': 1}, {'id': 2, 'passCount': 4, 'failCount': 0}, {'id': 5, 'passCount': 7, 'failCount': 3}, {'id': 6, 'passCount': 3, 'failCount': 0}]

Resources