I want to know how (if it is possible) to have the following function
calls not alter the original values of my two lists
(defun sort-value (Entry1 Entry2)
(> (car Entry1) (car Entry2)))
(defun get-values (hand)
(mapcar #'cadr (stable-sort hand #'sort-value)))
(setq flist '((1 2) (3 4) (2 1)))
(setq glist '((5 8) (8 3)))
(setq tlist (append flist glist))
(get-values tlist)
when I do this, not only do I get different values for successive
calls, but the value of glist and flist change.
·················@gmail.com" <················@gmail.com> writes:
> I want to know how (if it is possible) to have the following function
> calls not alter the original values of my two lists
>
> (defun sort-value (Entry1 Entry2)
> (> (car Entry1) (car Entry2)))
>
> (defun get-values (hand)
> (mapcar #'cadr (stable-sort hand #'sort-value)))
> (setq flist '((1 2) (3 4) (2 1)))
> (setq glist '((5 8) (8 3)))
> (setq tlist (append flist glist))
> (get-values tlist)
>
> when I do this, not only do I get different values for successive
> calls, but the value of glist and flist change.
;; you can prevent the values from changing by defining this:
(defun stable-sort-copied (fn seq &key (key #'identity))
(stable-sort (copy-seq seq) fn :key key))
;; sort-value is not necessary because STABLE-SORT takes a :key
;; argument
(defun get-values (hand)
;; are you sure that should be #'> ? (#'> means sort in reverse order)
(mapcar #'second (stable-sort-copied #'> hand :key #'first)))
;; you're making use of undefined behavior here:
;; 1) flist and glist have not been defined
;; 2) you're modifying quoted data
(defvar *glist* (copy-seq '((1 2) (3 4) (2 1))))
(defvar *flist* (copy-seq '((1 2) (3 4) (2 1))))
(get-values (append *flist* *glist*))
Thanks a lot for the help, however can you clarify for me exactly how
your stable-sort function works?
;so it takes in a function, a list and an optional key? What does the
(key #'identity) mean?
(fn seq &key (key #'identity))
;okay, so you call stable sort on a copy and how does fn :key key sort
it?
Thanks again for the useful code and critique of my code, I'm just a
bit unclear on a lot of stuff in the common lisp library, especially
stuff with passing functions abstractly.
(stable-sort (copy-seq seq) fn :key key))
Bill Atkins wrote:
> ·················@gmail.com" <················@gmail.com> writes:
>
> > I want to know how (if it is possible) to have the following function
> > calls not alter the original values of my two lists
> >
> > (defun sort-value (Entry1 Entry2)
> > (> (car Entry1) (car Entry2)))
> >
> > (defun get-values (hand)
> > (mapcar #'cadr (stable-sort hand #'sort-value)))
> > (setq flist '((1 2) (3 4) (2 1)))
> > (setq glist '((5 8) (8 3)))
> > (setq tlist (append flist glist))
> > (get-values tlist)
> >
> > when I do this, not only do I get different values for successive
> > calls, but the value of glist and flist change.
>
> ;; you can prevent the values from changing by defining this:
> (defun stable-sort-copied (fn seq &key (key #'identity))
> (stable-sort (copy-seq seq) fn :key key))
>
> ;; sort-value is not necessary because STABLE-SORT takes a :key
> ;; argument
> (defun get-values (hand)
> ;; are you sure that should be #'> ? (#'> means sort in reverse order)
> (mapcar #'second (stable-sort-copied #'> hand :key #'first)))
>
> ;; you're making use of undefined behavior here:
> ;; 1) flist and glist have not been defined
> ;; 2) you're modifying quoted data
>
> (defvar *glist* (copy-seq '((1 2) (3 4) (2 1))))
> (defvar *flist* (copy-seq '((1 2) (3 4) (2 1))))
>
> (get-values (append *flist* *glist*))
·················@gmail.com" <················@gmail.com> writes:
> Bill Atkins wrote:
>> ·················@gmail.com" <················@gmail.com> writes:
>>
>> > I want to know how (if it is possible) to have the following function
>> > calls not alter the original values of my two lists
>> >
>> > (defun sort-value (Entry1 Entry2)
>> > (> (car Entry1) (car Entry2)))
>> >
>> > (defun get-values (hand)
>> > (mapcar #'cadr (stable-sort hand #'sort-value)))
>> > (setq flist '((1 2) (3 4) (2 1)))
>> > (setq glist '((5 8) (8 3)))
>> > (setq tlist (append flist glist))
>> > (get-values tlist)
>> >
>> > when I do this, not only do I get different values for successive
>> > calls, but the value of glist and flist change.
>>
>> ;; you can prevent the values from changing by defining this:
>> (defun stable-sort-copied (fn seq &key (key #'identity))
>> (stable-sort (copy-seq seq) fn :key key))
>>
>> ;; sort-value is not necessary because STABLE-SORT takes a :key
>> ;; argument
>> (defun get-values (hand)
>> ;; are you sure that should be #'> ? (#'> means sort in reverse order)
>> (mapcar #'second (stable-sort-copied #'> hand :key #'first)))
>>
>> ;; you're making use of undefined behavior here:
>> ;; 1) flist and glist have not been defined
>> ;; 2) you're modifying quoted data
>>
>> (defvar *glist* (copy-seq '((1 2) (3 4) (2 1))))
>> (defvar *flist* (copy-seq '((1 2) (3 4) (2 1))))
>>
>> (get-values (append *flist* *glist*))
> Thanks a lot for the help, however can you clarify for me exactly how
> your stable-sort function works?
(Write your replies at the bottom of (or throughout) the message
you're replying to.)
stable-sort is a standard Common Lisp function. In retrospect, I'm
not sure why I made stable-sort-copied its own function. That
probably wasn't necessary, but to answer your question it takes a key
parameter so that its interface parallels that of the stable-sort
function.
> ;so it takes in a function, a list and an optional key? What does the
> (key #'identity) mean?
> (fn seq &key (key #'identity))
You should read up on parameter lists; look through
http://www.gigamonkeys.com/book .
> ;okay, so you call stable sort on a copy and how does fn :key key sort
> it?
What do you mean?
STABLE-SORT and SORT are both Common Lisp functions that accept a
comparison function, a sequence, and a key function. They sort the
sequence by comparing elements with the comparison function.
The :key argument lets you do things like:
(sort (copy-seq '((1 5 3) (2 5 4) (1 -2 4))) #'< :key #'second)
;; => ((1 -2 4) (1 5 3) (2 5 4))
As you can see, the result is sorted based on the numerical order of
the second element of each element in the sequence. :key is just a
way to avoid having to write the above function as
(sort (copy-seq '((1 5 3) (2 5 4) (1 -2 4)))
(lambda (a b) (< (second a) (second b))))
The function copies the sequence because SORT and STABLE-SORT are both
destructive. By sorting copies, the original versions are left
intact. You are calling sort on literal lists (that is, lists that
are quote), which is OK if your code is being interpreted but
potentially dangerous if your code is compiled. This is why the
quoted lists in the above cod have been copied.
> Thanks again for the useful code and critique of my code, I'm just a
> bit unclear on a lot of stuff in the common lisp library, especially
> stuff with passing functions abstractly.
> (stable-sort (copy-seq seq) fn :key key))
Read Practical Common Lisp, and some of these problems will become
clearer.
Thanks to both of you (and sorry about the screwed up response style, I
usually post at YABB forums) I understand sorting a lot better now.
Now, here's a related question. How can I have a list sorted by one
value, and then sorted by another value if the first two entries have
the same first value. For example, if I wanted to sort the list ((1 2)
(1 3) (2 0)) first by the first value, then by the second value, both
in descending (greatest to least) order (yielding ((2 0) (1 3) (1 2))
how would I do that? I could probably think up some convoluted
algorithm that did it, but is there any simple built in way to do it?
·················@gmail.com" <················@gmail.com> writes:
> Thanks to both of you (and sorry about the screwed up response style, I
> usually post at YABB forums) I understand sorting a lot better now.
> Now, here's a related question. How can I have a list sorted by one
> value, and then sorted by another value if the first two entries have
> the same first value. For example, if I wanted to sort the list ((1 2)
> (1 3) (2 0)) first by the first value, then by the second value, both
> in descending (greatest to least) order (yielding ((2 0) (1 3) (1 2))
> how would I do that? I could probably think up some convoluted
> algorithm that did it, but is there any simple built in way to do it?
For this, you need to write a special comparison function.
Something like:
(lambda (a b)
(cond
((> (first a) (first b)))
((= (first a) (first b)) (>= (second a) (second b)))))
(sort (copy-list '((1 2) (1 3) (2 0)))
(lambda (a b)
(cond
((> (first a) (first b)))
((= (first a) (first b)) (>= (second a) (second b))))))
--> ((2 0) (1 3) (1 2))
--
__Pascal Bourguignon__ http://www.informatimago.com/
WARNING: This product warps space and time in its vicinity.
·················@gmail.com" <················@gmail.com> writes:
> Thanks a lot for the help, however can you clarify for me exactly how
> your stable-sort function works?
> ;so it takes in a function, a list and an optional key? What does the
> (key #'identity) mean?
> (fn seq &key (key #'identity))
What do you want to know? How it works? Or how it's used?
(key (function identity)) means that if you don't give a :KEY
argument, it will use (function identity) by default.
> ;okay, so you call stable sort on a copy and how does fn :key key sort
> it?
It sorts the sequence by excuting a sort algorithm. Any sort
algorithm that has the stable feature, and hopefully that is not too
slow, at the discretion of the implementation.
Do you want to know what sort algorithms have been invented so far?
Have a look at: http://en.wikipedia.org/wiki/Sort_algorithm
> Thanks again for the useful code and critique of my code, I'm just a
> bit unclear on a lot of stuff in the common lisp library, especially
> stuff with passing functions abstractly.
> (stable-sort (copy-seq seq) fn :key key))
Most sequence processing functions take a test and a key functional argument.
The test argument is either a predicate or a function taking two
arguments and comparing them, for "equality" or "inequality".
The key argument is a function that extracts the value to be tested,
the _key_ of the objects to be processed.
For example, assuming the person-birth-date is stored as a universal
time (a cardinal),
(sort persons (function <=) :key (function person-birth-date))
sorts the persons by increasing birth date, but:
(sort persons (function string>=) :key (function person-name))
sorts the persons by decreasing names (from Z to A).
Of course, you could instead compare the persons directly, but it
would mean more work, since you'd have to implement the functions
person-name-greaterp and person-birth-date<=:
(sort persons (function person-name-greaterp))
(sort persons (function person-birth-date<=))
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
----------> http://www.netmeister.org/news/learn2quote.html <-----------
---> http://homepage.ntlworld.com/g.mccaughan/g/remarks/uquote.html <---
__Pascal Bourguignon__ http://www.informatimago.com/
·················@gmail.com" <················@gmail.com> writes:
> I want to know how (if it is possible) to have the following function
> calls not alter the original values of my two lists
Of course. Copy the sequence first!
> (defun sort-value (Entry1 Entry2)
> (> (car Entry1) (car Entry2)))
>
> (defun get-values (hand)
> (mapcar #'cadr (stable-sort hand #'sort-value)))
> (setq flist '((1 2) (3 4) (2 1)))
> (setq glist '((5 8) (8 3)))
> (setq tlist (append flist glist))
> (get-values tlist)
>
> when I do this, not only do I get different values for successive
> calls, but the value of glist and flist change.
(defun get-values (hand)
(map 'list (function cadr)
(stable-sort (copy-seq hand) (function >) :key (function car))))
--
__Pascal Bourguignon__ http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we. -- Georges W. Bush