Pregunta "Flat es mejor que anidado": ¿para datos y código?


Esta La pregunta me hizo pensar: ¿deberíamos aplicar el principio de que "el plano es mejor que anidar" tanto para los datos como para el código? Incluso cuando hay una "estructura de árbol lógica" para los datos?

En este caso, supongo que representaría a los niños como una lista de ID, en lugar de una lista real de niños, con todos los nodos en una sola lista:

[ {'id': 4, 'children': ()},
  {'id': 2, 'children': (1, 7)},
  {'id': 1, 'children': (6, 5)},
  {'id': 6, 'children': ()},
  {'id': 5, 'children': ()},
  {'id': 7, 'children': (3,)},
  {'id': 3, 'children': ()} ]

(Utilicé tuplas porque prefiero no darme la flexibilidad para mutar un objeto hasta que esa flexibilidad demuestre ser útil y utilizable de manera clara. En cualquier caso, nunca usaría None aquí en lugar de una secuencia vacía, porque complica la lógica y "los casos especiales no son lo suficientemente especiales"; aquí, no es para nada especial).

Ciertamente, esto es más corto, pero la estructura del árbol está oscurecida. ¿Eso contradice "lo explícito es mejor que lo implícito"?

Personalmente encuentro que "plano es mejor que anidado" tiene una aplicabilidad limitada, y en ninguna parte está cerca del aspecto más importante del Zen. (Ciertamente no podría hacer muchas de las buenas cosas de programación funcional que hago si no me permitiera anidar significativamente.) Sospecho que el problema con "anidado" es que requiere el cambio de contexto cuando comprendes la información. Realmente creo que esto es más un problema cuando sigo una lógica imperativa que para analizar datos o un código de estilo funcional, donde es más fácil nombrar mentalmente el bloque anidado y considerar su funcionamiento por separado del contexto externo.

¿Lo que usted dice?


32
2017-12-07 00:06


origen


Respuestas:


Tampoco preferiría intrínsecamente, sino usar lo que parezca más adecuado para la tarea.

Si la estructura es importante, anidar hace la vida simple. Si está operando regularmente sobre cada nodo, la estructura plana hace que sea fácil de usar for node in tree. Por supuesto, si defines tu propia clase, es bastante fácil abstraerla para que ambas opciones sean simples; pero puede ser más difícil de usar con sistemas externos, como la conversión a JSON.


6
2017-12-07 00:41



¿Deberíamos aplicar el principio de que "el plano es mejor que anidar" a los datos y al código?

No.

Incluso cuando hay una "estructura de árbol lógica" para los datos?

Eso es lo que "plano es mejor que anidado" no se aplica a los datos. Solo para codificar.

... la estructura del árbol está oscurecida. ¿Eso contradice "lo explícito es mejor que lo implícito"?

Ni siquiera es comparable. El "árbol plano" es una implementación común de SQL porque SQL no puede manejar la recursión indefinida de un árbol apropiado.

Comparar el Zen de Python (el lenguaje) con el diseño de la estructura de datos no tiene sentido. Los dos no son más comparables que el número "2" y dividen un ladrillo de queso en "2" piezas. Una es una cosa, la otra es una acción.

Las estructuras de datos son cosas.

Python describe acciones.


11
2017-12-07 01:07



Esta es una pregunta completamente subjetiva. La respuesta es, depende."

Depende del uso principal de sus datos. Si continuamente tiene que hacer referencia a la estructura anidada, entonces tiene sentido representarla de esa manera. Y si nunca hace referencia a la representación plana, excepto cuando construye la estructura anidada, ¿por qué tener la estructura plana en absoluto?

La representación "plana" es uno de los conceptos básicos del modelo de base de datos relacional: cada tipo de datos existe en una tabla solo para ese tipo, y cualquier relación entre los elementos está contenida en tablas separadas. Es una abstracción útil, pero a veces es difícil trabajar con código. Por otro lado, procesar todos los datos de un tipo particular es trivial.

Considere, por ejemplo, si quería encontrar todos los descendientes del registro con id 2 en sus datos de ejemplo. Si los datos ya están en la jerarquía (es decir, la representación nativa es la estructura "anidada"), es trivial localizar la identificación del registro 2 y luego recorrer sus hijos, hijos de niños, etc.

Pero si la representación nativa es secuencial como lo has mostrado, entonces tengo que pasar por todo el conjunto de datos para crear la estructura jerárquica y entonces encuentra el registro 2 y sus hijos.

Entonces, como dije, "depende".


9
2017-12-07 00:42



"Todo debe hacerse lo más simple posible, pero no más simple". Flat es más simple que anidado. Si está tratando con datos con pertinente anidar, luego aplanarlo probablemente viole la parte "pero no es más simple". Tomé el Zen of Python en su lugar para alentarte a no complicar tu vida con la anidación que realmente no necesitas, como un archivo de configuración XML donde un formato plano más simple podría ser suficiente.


4
2017-12-11 07:22



¿Eso contradice "explícito es   mejor que implícito "?

Sí, especialmente cuando ser explícito le impide dispararse implícitamente en el pie. El "árbol" en su ejemplo puede tener múltiples padres que afirman poseer los mismos hijos. También puede tener múltiples nodos raíz (y lo hace: 2 es un nodo raíz; 4 es una raíz además de un nodo hoja).


3
2017-12-07 00:52



Esta pregunta no puede responderse "en general": no hay una respuesta correcta.

Para este ejemplo en particular, en realidad me gusta más la estructura del árbol. Sin saber nada sobre la aplicación original, y solo mirando la estructura, la relación entre los elementos es obvia. Con la estructura plana, tengo que leer alguna documentación o código de aplicación para "saber" que su tupla de hijos se refiere a los identificadores.

La estructura del árbol es autodidacta, la estructura plana no.


3
2017-12-07 00:58