2010-05-25 8 views
6

en Python, que podría hacer algo comolistas de extraer/cortar/reordenar en (emacs) lisp?

i = (0, 3, 2) 
x = [x+1 for x in range(0,5)] 
operator.itemgetter(*i)(x) 

para obtener (1, 4, 3). En (emacs) Lisp, que escribió esta función se llama extracto que hace algo similar,

(defun extract (elems seq) 
    (mapcar (lambda (x) (nth x seq)) elems)) 

(extract '(0 3 2) (number-sequence 1 5)) 

pero siento que no debería ser algo construido en? Todo lo que sé es first, last, rest, nth, car, cdr ... ¿Cuál es el camino a seguir? ~ Gracias de antemano ~

Respuesta

4

Si su problema es la velocidad, utilice (vector 1 2 3 4 5) en lugar de una lista y (índice vec) para obtener el elemento.

(defun extract (elems seq) 
    (let ((av (vconcat seq))) 
    (mapcar (lambda (x) (aref av x)) elems))) 

Si va a extraer de la misma secuencia varias veces, por supuesto, tiene sentido para almacenar la secuencia en un vector de una sola vez. Las listas de Python son de hecho matrices unidimensionales, el equivalente en LISP son vectores.

+0

No lo sabía. Entonces, para este problema, tengo que decidir si la sobrecarga de crear un vector vale la sobrecarga adicional de acceso de tiempo constante. – hatmatrix

2

Solo he hecho scripts simples en elisp, pero es un lenguaje relativamente pequeño. Y extract es una función muy ineficiente en listas enlazadas, que es la estructura de datos predeterminada en emacs lisp. Por lo tanto, es poco probable que esté incorporado.

Su solución es la más sencilla. Es n^2, pero para hacerlo más rápido requiere mucho más código.

A continuación se muestra una pista sobre cómo podría funcionar, pero también podría ser la base totalmente fuera:

  1. tipo elems (n log n)
  2. crear un mapa que mapea los elementos en ordenados elem a su índices en el original elem (probablemente n log n, quizás n)
  3. iterar a través de seq y ordenar elem. Mantener sólo los índices en ordenados elem (probablemente n, tal vez n log n, dependiendo de si se trata de un mapa hash o un mapa de árbol)
  4. Ordenar el resultado por los valores de la elem mapeo (n log n)
+0

Genial, gracias ... – hatmatrix

1

de My Lisp Experiences and the Development of GNU Emacs:

había gente en esos días, en 1985, que tenía máquinas de un megabyte sin memoria virtual. Querían poder usar GNU Emacs. Esto significaba que tenía que mantener el programa lo más pequeño posible.

Por ejemplo, en ese momento la única construcción de bucle era 'while', que era extremadamente simple. No había forma de salir de la declaración 'while', solo tenía que hacer un catch y un throw, o probar una variable que ejecutara el ciclo. Eso muestra cuán lejos estaba presionando para mantener las cosas pequeñas. No teníamos 'caar' y 'cadr', etc. "Exprimir todo lo posible" fue el espíritu de GNU Emacs, el espíritu de Emacs Lisp, desde el principio.

Obviamente, las máquinas son más grandes ahora, y ya no lo hacemos de esa manera. Ponemos 'caar' y 'cadr', y así sucesivamente, y podríamos poner otro bucle construir uno de estos días.

Así que mi suposición es, si no lo ves, no está allí.