В Python Вы могли бы сделать что-то как
i = (0, 3, 2)
x = [x+1 for x in range(0,5)]
operator.itemgetter(*i)(x)
добираться (1, 4, 3)
. В (emacs) шепелявость я записал эту функцию, вызванную извлечение, которое делает что-то подобное,
(defun extract (elems seq)
(mapcar (lambda (x) (nth x seq)) elems))
(extract '(0 3 2) (number-sequence 1 5))
но я чувствую, что должно быть что-то, встроил? Все, что я знаю, first, last, rest, nth, car, cdr
... Что состоит в том, чтобы пойти путь? ~ Заранее спасибо ~
Если ваша проблема заключается в скорости, то используйте (vector 1 2 3 4 5) вместо списка, и (aref vec index) для получения элемента.
(defun extract (elems seq)
(let ((av (vconcat seq)))
(mapcar (lambda (x) (aref av x)) elems)))
Если вы собираетесь извлекать из одной и той же последовательности много раз, конечно, имеет смысл хранить последовательность в векторе только один раз. Списки в Python действительно являются одномерными массивами, эквивалентом в LISP являются векторы.
Из Мои впечатления от Lisp и разработка GNU Emacs :
В те дни, в 1985 году, были люди, у которых были машины размером в один мегабайт без виртуальной памяти. Они хотели иметь возможность использовать GNU Emacs. Это означало, что я должен был сделать программу как можно меньше.
Например, в то время единственной циклической конструкцией было «while», что было чрезвычайно просто. Невозможно было прервать выполнение оператора while, вам просто нужно было выполнить catch и throw или протестировать переменную, которая запускала цикл. Это показывает, как далеко я зашел, чтобы все было маленьким. У нас не было «caar», «cadr» и так далее; «Выжать все возможное» было духом GNU Emacs, духом Emacs Lisp с самого начала.
Очевидно, что машины сейчас больше, и мы больше так не делаем. Мы добавляем «caar», «cadr» и т. Д., И, возможно, однажды мы добавим еще одну циклическую конструкцию.
Я предполагаю, что если вы этого не видите, значит, его там нет.
Я делал только простые сценарии на elisp, но это относительно небольшой язык. И extract
- это очень неэффективная функция для связных списков, которые являются структурой данных по умолчанию в emacs lisp. Поэтому она вряд ли будет встроенной.
Ваше решение - лучшее прямолинейное решение. Оно n^2, но чтобы сделать его быстрее, требуется гораздо больше кода.
Ниже приведено предположение, как это может работать, но оно может быть и совершенно неверным:
elems
(n log n)elem
на их индексы в исходном elem
(вероятно, n log n, возможно n)seq
и отсортированный elem
. Сохраните только индексы в отсортированном elem
(возможно n, возможно n log n, в зависимости от того, хэш-карта это или древовидная карта)elem
(n log n)