简体   繁体   中英

removing isolated vertices in networkx

The documentation says that isolated vertices in graph can be obtained using networkx.isolates( G ). It adds that the isolated vertices can be removed from a graph G using the code G .remove_nodes_from(nx.isolates( G )).

https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.algorithms.isolate.isolates.html

文档截图(上面的url)

But I get the run time error "dictionary changed size during iteration" when I run the code.

Error report:-
>>> G.remove_nodes_from(nx.isolates(G)) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/iiitdm/anaconda2/lib/python2.7/site-packages/networkx/classes/graph.py", line 617, in remove_nodes_from for n in nodes: File "/home/iiitdm/anaconda2/lib/python2.7/site-packages/networkx/algorithms/isolate.py", line 94, in <genexpr> return (n for n, d in G.degree() if d == 0) File "/home/iiitdm/anaconda2/lib/python2.7/site-packages/networkx/classes/reportviews.py", line 443, in __iter__ for n in self._nodes: RuntimeError: dictionary changed size during iteration

It is understandable and was expected because (I think) the generator object created using the function isolates() changes with G and hence changing graph G while it is being 'iterated' should give a similar error. Then that line in the documentation must be wrong, isn't it? Am I completely off the mark? I am pretty new to python.

By the way, the object returned by networkx.isolates() is a generator object.

Thank you

I think you are right, submit a documentation patch?

also you can cast the generator to a list to get around this:

G.remove_nodes_from(list(nx.isolates(G)))

But why does your work-around work? I don't understand it; the situation has not changed!

I would have to look at their code, but my hunch is the lazyness of a generator is working against it based on the Exception message.

Casting to list, the collection is created before it is fed as an argument, so there is no side effects on the object as it is iterated.

As noted from @Dyz's answer, the documentation is correct, you are using Nx 2.0.

https://networkx.github.io/documentation/networkx-2.0/reference/algorithms/generated/networkx.algorithms.isolate.isolates.html

Does this collection creation before fed as argument behaviour hold for any kind of cast (say to dict or set) ?

Well not quite (a set will work) dict won't because it wants a pair of items. list and set when called like a function (and dict but again it needs pairs (a list of tuples will work)) calls __iter__

Generators have __iter__ which makes them iterables (+ a lot of other objects). Generators are really nice to have to address various usecases, for example when you have a large collection of items, and need to loop through them multiple times, it can save you on runtime complexity.

However, there is nuances such as what you ran into, where you have to understand some of the internals for proper use.

You are looking at the docs for 1.X while using 2.X. Unfortunately the search engine ranking is higher for the 1.X documentation.

In networkx 2.X isolates is a generator object.

The current stable docs will add list() to the example code.

https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.isolate.isolates.html

In [107]: nx.isolates(G)
Out[107]: <generator object isolates.<locals>.<genexpr> at 0x7fa499cd8e60>

The migration guide may help out if you are expecting 1.X behavior too.

https://networkx.github.io/documentation/stable/release/migration_guide_from_1.x_to_2.0.html

You confuse networkx-2.0 (where isolates returns an iterator) and the documentation for networkx-1.10 (where isolates returns a list). Your code would work perfectly fine in networkx-1.10 . Applying list to isolates in 2.0 reduces the situation to what existed in 1.10.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM