2010-05-25 14 views
6

W Pythonie można zrobić coś takiegowyciąg/plaster/kolejność list w (emacs) seplenienie?

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

dostać (1, 4, 3). W (emacs) LISP, napisałem tę funkcję o nazwie ekstrakt, który robi coś podobnego,

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

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

ale czuję się jak nie powinno być coś wbudowany? Wszystko, co wiem, to first, last, rest, nth, car, cdr ... Jaka jest droga? ~ Z góry dziękuję ~

Odpowiedz

4

Jeśli Twoim problemem jest szybkość, użyj (wektor 1 2 3 4 5) zamiast listy i (aref indeks vec), aby uzyskać element.

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

Jeśli zamierzasz wielokrotnie wydobywać z tej samej sekwencji, to sensownie jest przechowywać sekwencję w wektorze tylko raz. Listy Pythona są rzeczywiście jednowymiarowymi tablicami, odpowiednikami w LISP są wektory.

+0

Nie wiedziałem tego. Tak więc dla tego problemu muszę zdecydować, czy narzut tworzenia wektora jest wart dodatkowy dodatkowy czas stały. – hatmatrix

2

Wykonałem tylko proste skrypty w elispie, ale jest to stosunkowo mały język. I extract jest bardzo nieefektywną funkcją na połączonych listach, która jest domyślną strukturą danych w emacs-sepp. Jest więc mało prawdopodobne, aby był wbudowany.

Twoje rozwiązanie jest najlepszym rozwiązaniem prostym. To n^2, ale przyspieszenie wymaga o wiele więcej kodu.

Poniżej znajduje się domyślać, jak to może działać, ale może to być również całkowicie wyłączyć podstawa:

  1. rodzaj elems (n log n)
  2. stworzyć mapę, która mapuje elementy w sortowanych elem do ich indeksy w oryginalnym numerze elem (prawdopodobnie n log n, może n)
  3. iterują przez seq i sortują elem. Przechowywać tylko indeksy posortowanych elem (prawdopodobnie n, może n log n, w zależności od tego, czy jest to skrót map lub drzewa mapa)
  4. sortowania wynik przez wartości odwzorowania elem (n log n)
+0

Świetnie - dziękuję ... – hatmatrix

1

Od My Lisp Experiences and the Development of GNU Emacs:

tam byli ludzie w tamtych czasach, w 1985 roku, która miała jednego megabajta maszyn bez pamięci wirtualnej. Chcieli móc korzystać z GNU Emacs. Oznaczało to, że musiałem trzymać program tak mały, jak to tylko możliwe.

Na przykład w tym czasie jedyną konstrukcją pętli była "while", co było niezwykle proste. Nie było sposobu na wyrwanie się z "while", wystarczyło złapać i rzucić, lub przetestować zmienną, która uruchomiła pętlę. To pokazuje, jak daleko naciskałem, aby zachować małe rozmiary. Nie mieliśmy "caar" i "cadr" i tak dalej; "Wycisnąć wszystko, co możliwe" był duchem GNU Emacs, duchem Emacsa Lispa, od samego początku.

Oczywiście, maszyny są teraz większe i nie robimy tego w ten sposób. Wstawiamy "caar" i "cadr" i tak dalej, i możemy wstawić kolejny konstrukt pętli jednego z tych dni.

Zgaduję, że jeśli go nie widzisz, nie ma go.