1 """
2 Read and write NetworkX graphs.
3
4 Note that NetworkX graphs can contain any hashable Python object as
5 node (not just integers and strings). So writing a NetworkX graph
6 as a text file may not always be what you want: see write_gpickle
7 and gread_gpickle for that case.
8
9 This module provides the following :
10
11 Edgelist format:
12 Useful for connected graphs with or without edge data.
13
14 write_edgelist(G, path)
15 G=read_edgelist(path)
16
17
18 """
19 __author__ = """Aric Hagberg (hagberg@lanl.gov)\nDan Schult (dschult@colgate.edu)"""
20 __date__ = """"""
21 __credits__ = """"""
22 __revision__ = ""
23
24
25
26
27
28
29
30 import codecs
31 import locale
32 import string
33 import sys
34 import time
35
36 from networkx.utils import is_string_like,_get_fh
37 import networkx
38
39
41 """Write graph G in edgelist format on file path.
42
43 See read_edgelist for file format details.
44
45 >>> write_edgelist(G, "file.edgelist")
46
47 path can be a filehandle or a string with the name of the file.
48
49 >>> fh=open("file.edgelist")
50 >>> write_edgelist(G,fh)
51
52 Filenames ending in .gz or .bz2 will be compressed.
53
54 >>> write_edgelist(G, "file.edgelist.gz")
55
56 The file will use the default text encoding on your system.
57 It is possible to write files in other encodings by opening
58 the file with the codecs module. See doc/examples/unicode.py
59 for hints.
60
61 >>> import codecs
62 >>> fh=codecs.open("file.edgelist",encoding='utf=8') # use utf-8 encoding
63 >>> write_edgelist(G,fh)
64
65
66 """
67 fh=_get_fh(path,mode='w')
68
69 pargs=comments+" "+string.join(sys.argv,' ')
70 fh.write("%s\n" % (pargs))
71 fh.write(comments+" GMT %s\n" % (time.asctime(time.gmtime())))
72 fh.write(comments+" %s\n" % (G.name))
73 for e in G.edges():
74 for n in e:
75 if n is None: continue
76 if is_string_like(n):
77 fh.write(n+delimiter)
78 else:
79 fh.write(str(n)+delimiter)
80 fh.write("\n")
81
82 -def read_edgelist(path, comments="#", delimiter=' ',
83 create_using=None, nodetype=None, edgetype=None):
84 """Read graph in edgelist format from path.
85
86 >>> G=read_edgelist("file.edgelist")
87
88 path can be a filehandle or a string with the name of the file.
89
90 >>> fh=open("file.edgelist")
91 >>> G=read_edgelist(fh)
92
93 Filenames ending in .gz or .bz2 will be compressed.
94
95 >>> G=read_edgelist("file.edgelist.gz")
96
97 nodetype is an optional function to convert node strings to nodetype
98
99 For example
100
101 >>> G=read_edgelist("file.edgelist", nodetype=int)
102
103 will attempt to convert all nodes to integer type
104
105 Since nodes must be hashable, the function nodetype must return hashable
106 types (e.g. int, float, str, frozenset - or tuples of those, etc.)
107
108 create_using is an optional networkx graph type, the default is
109 Graph(), a simple undirected graph
110
111 >>> G=read_edgelist("file.edgelist",create_using=DiGraph())
112
113
114 The comments character (default='#') at the beginning of a
115 line indicates a comment line.
116
117 The entries are separated by delimiter (default=' ').
118 If whitespace is significant in node or edge labels you should use
119 some other delimiter such as a tab or other symbol.
120
121 Example edgelist file format::
122
123 # source target
124 a b
125 a c
126 d e
127
128 or for an XGraph() with edge data
129
130 # source target data
131 a b 1
132 a c 3.14159
133 d e apple
134
135 """
136 if create_using is None:
137 G=networkx.Graph()
138 else:
139 try:
140 G=create_using
141 G.clear()
142 except:
143 raise TypeError("Input graph is not a networkx graph type")
144
145
146 if hasattr(G,'allow_multiedges')==True:
147 xgraph=True
148 else:
149 xgraph=False
150
151 fh=_get_fh(path)
152
153 for line in fh.readlines():
154 line = line[:line.find(comments)].strip()
155 if not len(line): continue
156
157
158
159
160 s=line.split(delimiter)
161 if len(s)==2:
162 (u,v)=s
163 d=None
164 elif len(s)==3:
165 (u,v,d)=s
166 else:
167 raise TypeError("Failed to read line: %s"%line)
168
169
170 try:
171 (u,v)=map(nodetype,(u,v))
172 except:
173 raise TypeError("Failed to convert edge (%s, %s) to type %s"\
174 %(u,v,nodetype))
175 if d is not None and edgetype is not None:
176
177 try:
178 d=edgetype(d)
179 except:
180 raise TypeError("Failed to convert edge data (%s) to type %s"\
181 %(d, edgetype))
182
183 if xgraph:
184 G.add_edge(u,v,d)
185 else:
186 G.add_edge(u,v)
187
188 return G
189
190
191
193 import doctest
194 suite = doctest.DocFileSuite('tests/readwrite/edgelist.txt',package='networkx')
195 return suite
196
197
198 if __name__ == "__main__":
199 import os
200 import sys
201 import unittest
202 if sys.version_info[:2] < (2, 4):
203 print "Python version 2.4 or later required for tests (%d.%d detected)." % sys.version_info[:2]
204 sys.exit(-1)
205
206 nxbase=sys.path[0]+os.sep+os.pardir
207 sys.path.insert(0,nxbase)
208 unittest.TextTestRunner().run(_test_suite())
209