La documentación dice que los vértices aislados en el gráfico se pueden obtener usando networkx.isolates( G ). Agrega que los vértices aislados se pueden eliminar de un gráfico G usando el código G .remove_nodes_from(nx.isolates( G )).
Pero aparece el error de tiempo de ejecución "diccionario cambió de tamaño durante la iteración" cuando ejecuto el código.
Reporte de error:-
>>> 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
Es comprensible y se esperaba porque (creo) el objeto generador creado con la función aislar() cambia con G y, por lo tanto, cambiar el gráfico G mientras se 'itera' debería dar un error similar. Entonces esa línea en la documentación debe estar mal, ¿no? ¿Estoy completamente fuera de lugar? Soy bastante nuevo en Python.
Por cierto, el objeto devuelto por networkx.isolates() es un objeto generador.
Gracias
Creo que tienes razón, ¿enviar un parche de documentación?
también puede enviar el generador a una lista para evitar esto:
G.remove_nodes_from(list(nx.isolates(G)))
Pero, ¿por qué funciona su solución alternativa? no lo entiendo; la situación no ha cambiado!
Tendría que mirar su código, pero mi corazonada es que la pereza de un generador está trabajando en su contra según el mensaje de Excepción.
Convirtiendo a la lista, la colección se crea antes de que se alimente como un argumento, por lo que no hay efectos secundarios en el objeto a medida que se itera.
Como se señaló en la respuesta de @Dyz, la documentación es correcta, está utilizando Nx 2.0.
¿Esta creación de colección antes de alimentar como comportamiento de argumento se mantiene para cualquier tipo de conversión (por ejemplo, para dictar o establecer)? –
Bueno, no del todo (un conjunto funcionará) dict no lo hará porque quiere un par de artículos. list y set cuando se llama como una función (y dict pero de nuevo necesita pares (una lista de tuplas funcionará)) llama a __iter__
Los generadores tienen __iter__ que los hace iterables (+ muchos otros objetos). Los generadores son realmente buenos para tener que abordar varios casos de uso, por ejemplo, cuando tiene una gran colección de elementos y necesita recorrerlos varias veces, puede ahorrarle complejidad en el tiempo de ejecución.
Sin embargo, hay matices como lo que encontró, donde debe comprender algunas de las partes internas para un uso adecuado.
Está consultando los documentos de 1.X mientras usa 2.X. Desafortunadamente, la clasificación del motor de búsqueda es más alta para la documentación 1.X.
En networkx 2.X, los aislamientos son un objeto generador.
Los documentos estables actuales agregarán list() al código de ejemplo.
In [107]: nx.isolates(G) Out[107]: <generator object isolates.<locals>.<genexpr> at 0x7fa499cd8e60>La guía de migración puede ser útil si también espera un comportamiento 1.X.
https://networkx.github.io/documentation/stable/release/migration_guide_from_1.x_to_2.0.html
Confunde networkx-2.0 (donde los isolates devuelven un iterador) y la documentación para networkx-1.10 (donde los isolates devuelven una lista). Su código funcionaría perfectamente bien en networkx-1.10 . La aplicación de la list a los isolates en 2.0 reduce la situación a lo que existía en 1.10.