2009-10-09 7 views
6

Al ver las comprensiones en Python y Javascript, hasta ahora no puedo ver algunas de las características principales que considero más poderosas en las comprensiones en idiomas como Haskell.Las comprensiones en Python y Javascript son solo muy básicas.

¿Permiten cosas como múltiples generadores? ¿O son solo una forma básica de filtro de mapas?

Si no permiten múltiples generadores, los encuentro bastante decepcionantes, ¿por qué se han dejado esas cosas?

Respuesta

12

Python permite que varios generadores:

>>> [(x,y,x*y) for x in range(1,5) for y in range(1,5)] 
[(1, 1, 1), (1, 2, 2), (1, 3, 3), (1, 4, 4), 
(2, 1, 2), (2, 2, 4), (2, 3, 6), (2, 4, 8), 
(3, 1, 3), (3, 2, 6), (3, 3, 9), (3, 4, 12), 
(4, 1, 4), (4, 2, 8), (4, 3, 12), (4, 4, 16)] 

Y también Restricciones:

>>> [(x,y,x*y) for x in range(1,5) for y in range(1,5) if x*y > 8] 
[(3, 3, 9), (3, 4, 12), (4, 3, 12), (4, 4, 16)] 

Actualizar: JavaScript de la sintaxis es similar (resultados para m utilizando la javascript shell en Firefox):

var nums = [1, 2, 3, 21, 22, 30]; 
var s = eval('[[i,j] for each (i in nums) for each (j in [3,4]) if (i%2 == 0)]'); 
s.toSource(); 
[[2, 3], [2, 4], [22, 3], [22, 4], [30, 3], [30, 4]] 

(Por alguna razón, algo sobre la materia contexto se evalúa en la cáscara de JavaScript requiere el direccionamiento indirecto eval para tener listas por comprensión funcionan. Javascript dentro de una etiqueta <script> no requiere que, por supuesto)

+0

Cool. Ahora, todas las necesidades de Python son coincidencia de patrones en generadores. Y generalizar las comprensiones más allá de las secuencias a otras mónadas. Y er - un Typerchecker. :) – RD1

+2

No. Python no es Haskell. La verificación de tipos está en contra de la filosofía de python. –

+0

Según lo que he leído, la comprobación de tipo estático opcional se consideró seriamente para Python durante un tiempo antes de ser rechazada. Entonces, no creo que pueda ser tan contrario a la filosofía. Y la historia nos dice que los lenguajes como Lisp sin tipo de comprobadores no escalan bien, incluso con pruebas unitarias. Personalmente, me resulta difícil enseñar a mis alumnos cuando no pueden confiar en el IDE para comprender el tipo de cosas: los tipos estáticos hacen que la programación sea mucho más fácil cuando se aprende a programar con un buen IDE. – RD1

3

Sí, puede tener múltiples iterables en un Python list comprehension:

>>> [(x,y) for x in range(2) for y in range(3)] 
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)] 
+0

Genial, me alegro. Me pregunto por qué no pude encontrar esta información fácilmente ... ninguno de los ejemplos en Wikipedia o en otro lugar parece incluir esto. Ahora todo lo que no me gusta es la sintaxis en comparación con Haskell. :) ¿Qué hay de Javascript? – RD1

1

Añadir una sentencia if, así ...

>>> [(x,y) for x in range(5) for y in range(6) if x % 3 == 0 and y % 2 == 0] 
[(0, 0), (0, 2), (0, 4), (3, 0), (3, 2), (3, 4)] 
1

de comprensión es muy potente en Haskell, en gran medida debido a Haskell es funcional, por lo tiene mucho sentido para ellos. Python no funciona así que tiene menos sentido.

Puede hacer muchas cosas complejas con comprensiones en Python, pero rápidamente se vuelve difícil de leer, lo que le hace perder todo el propósito (lo que significa que debe hacerlo de otra manera).

Sin embargo, como se señala aquí, python permite múltiples generadores en las comprensiones.

+1

Lo último que escuché, uno de los puntos fuertes de Python es que es compatible con la programación funcional y abarca cosas como los cierres. ¿Hay alguna otra manera de hacer el equivalente de una comprensión de generador múltiple que sea más elegante en Python? – RD1

+0

Python tiene un soporte restringido para programación funcional, principalmente debido al hecho de que las funciones de Python son verdaderos objetos. También tomó prestados algunos constructos de lenguajes funcionales. Pero sigue siendo principalmente y básicamente un lenguaje imperativo orientado a objetos. Además, la definición pythonesque de "elegancia" es * legibilidad *. Una comprensión de generador múltiple generalmente es mucho más legible (al menos para la mayoría de los programadores) escrito como un viejo bucle "para". –

+0

@Rowan: Sí, para bucles, por lo general. También debe considerar crear sus propios generadores con 'yield' o posiblemente' __next__'. –

Cuestiones relacionadas