In python, you might do something like
i = (0, 3, 2)
x = [x+1 for x in range(0,5)]
operator.itemgetter(*i)(x)
to get (1, 4, 3)
.
In (emacs) lisp, I wrote this function called extract which does something similar,
(defun extract (elems seq)
(mapcar (lambda (x) (nth x seq)) elems))
(extract '(0 3 2) (number-sequence 1 5))
but I feel like there should be something built in? All I know is first, last, rest, nth, car, cdr
... What's the way to go? ~ Thanks in advance ~
If your problem is the speed then use (vector 1 2 3 4 5) instead of a list, and (aref vec index) to get the element.
(defun extract (elems seq)
(let ((av (vconcat seq)))
(mapcar (lambda (x) (aref av x)) elems)))
If you're going to extract from the same sequence many times of course it make sense to store the sequence in a vector just once. Python lists are indeed one-dimensional arrays, the equivalent in LISP are vectors.
I've only done simple scripting in elisp, but it's a relatively small language. And extract
is a very inefficient function on linked lists, which is the default data structure in emacs lisp. So it's unlikely to be built-in.
Your solution is the best straightforward one. It's n^2, but to make it faster requires a lot more code.
Below is a guess at how it might work, but it might also be totally off base:
elems
(n log n)elem
to their indices in original elem
(probably n log n, maybe n)seq
and sorted elem
. Keep only the indices in sorted elem
(probably n, maybe n log n, depending on whether it's a hash map or a tree map)elem
mapping (n log n)If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With