This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Replacing elements in a list

23 posts · 8452 views

Hi All.
I need some help cause I have no enough knowledge to complete my task. So what's the goal.
I need to define a a function which places a simbol * before every less-than-zero (-1..-5 etc.) element.
For ex. I've (setq a'(1 ,2 ,3 ,-1, -5 ,7 ,-8) a list. So then I should call a function forex MyFunc(x)
(Myfunc A) then I should get (1, 2, 3 ,*-1, *-5, 7 ,8) (i use commas here to separate elements of course no commas in the code).
I'm trying to write this function already 5 days but still can't .
Can someone help me?

So what I get
(defun myfunc (a x)
 (cond ((null x) nil)
 ((< (car x) 0) (cons a (myfunc a (cdr x))))
 (T (cons (car x) (myfunc a (cdr x))))))
But it just replaces every less-than-zero in a list X to A. But I need a function with just one parameter X-which represents a list.

Re: Replacing elements in a list

What kind of value do you expect "*-1" to be? The way you write it, it can only be a symbol, but the other elements seem to be numbers.

What kind of values should the input list contain?

By the way, you should properly indent your code to help with reading it. A nice explanation can be found in Practical Common Lisp.
"Just throw more hardware at it" is the root of all evil.
Svante

Re: Replacing elements in a list

If the symbol * has to be before as element of the list your code is nearly correct:
(defun myfunc (a x)
  (cond ((null x) nil)
    ((< (car x) 0)
      (append (list a (car x)) (myfunc a (cdr x))))
    (t
      (cons (car x) (myfunc a (cdr x))))))
If you want to attach to things into a string you can use format nil ... (nil indicating that output to string, and you can make strings into a symbol with intern. Left as an exercise.

Last edited by Jasper on , edited 1 time in total.

Re: Replacing elements in a list

Break it up into two parts. Write a function that returns either the positive number or the... other thing, then use MAPCAR to apply it to the list.
(defun do-strange-thing (list)
  (mapcar (lambda (number)
            (if (plusp number)
                number
                (cons '* number))) ; Replace this with what you actually wanted.
          list))
Or of course you could write the same thing recursively (or with DO or LOOP) if you wanted, but this strikes me as cleaner.

Re: Replacing elements in a list

Thanks for your attention.

Ok let me to explain.

So i have a list A(1 2 4 -1 3 -2 6 -8). As you see here is some members which has <0 values For ex. -1 -2 -8. and some members are >0 ok just simple list. ;)
Now the goal. I need a function which place a symbol * before every member which has <0 value. Thats all! :o

One more ex.

list A before
(1 2 4 -1 3 -2 6 -8)

list after A
(1 2 4 *-1 3 *-2 6 *-8)

So if I have a member which value is <0 then I should add a symbol * before. Or by other word it should be combined in one member * and a number. Here: *-1 is one single member and *-8 is another single member

Re: Replacing elements in a list

Lispoman wrote:Now the goal. I need a function which place a symbol * before every member which has <0 value. Thats all! :o
That seems like a bad idea. What can you do with a symbol like "*-1"?

Re: Replacing elements in a list

Lispoman wrote:So if I have a member which value is <0 then I should add a symbol * before. Or by other word it should be combined in one member * and a number. Here: *-1 is one single member and *-8 is another single member
Changing Paul Donnelly's code you can do this in a quite simple way. To take a number (e.g. -3) and return the symbol add a * before it (e.g. *-3), you can use this function:
(defun add-* (number)
  (intern (format nil "*~a" number)))
This should be more than enough information for you to do what you have in mind. This looks like homework and I don't want to do it for you.

But this is a very weird task. This takes a number and returns a symbol. If this is homework, are you sure you haven't gotten the exercise wrong? Because I believe that "add a symbol * before every number in the list", is to do something like this:
(add-*-before-negatives '(1 2 4 -1 3 -2 6 -8)) => (1 2 4 * -1 3 * -2 6 * -8)
If this is not homework, then I have absolutely no idea of how this can be useful, and you must be doing things the wrong way.

Re: Replacing elements in a list

Lispoman wrote:Hi All.
I need some help cause I have no enough knowledge to complete my task. So what's the goal.
I need to define a a function which places a simbol * before every less-than-zero (-1..-5 etc.) element.
For ex. I've (setq a'(1 ,2 ,3 ,-1, -5 ,7 ,-8) a list. So then I should call a function forex MyFunc(x)
(Myfunc A) then I should get (1, 2, 3 ,*-1, *-5, 7 ,8) (i use commas here to separate elements of course no commas in the code).
I rather suspect you want (1 2 3 * -1 * -5 7 8) — i.e., with * symbols appearing before the negative values, not symbols like *-1 as everyone seems to be assuming.
(defun myfunc (a x)
 (cond ((null x) nil)
 ((< (car x) 0) (cons a (myfunc a (cdr x))))
 (T (cons (car x) (myfunc a (cdr x))))))
But it just replaces every less-than-zero in a list X to A. But I need a function with just one parameter X-which represents a list.
Is this homework?

I'd write
(loop for x in list when (minusp x) collect '* collect x)

Re: Replacing elements in a list

Yes you right. This code has no any practical value but. I need a sample how to do such a transform because I need to use it in some functions. I did'n post my code here cause it will take a lot to explain the purpose but I need such a so called transfirmation of the list.
A function above is just what I need It adds a * symbol to anything. But how to connect it with my code I've tryed
(defun add-*(number)
	   (intern (format nil "*~a" number)))
	   
(defun myfunc (x)
           (cond ((null x) nil)
                 ((< (car x) 0) (cons (add-* (car x)) (myfunc (add-* (car x)) (cdr x)))
                      (T (cons (car x) (myfunc (add-* (car x)) (cdr x)))))))
But it returns NIL insted of list.

Re: Replacing elements in a list

Yeea! Solved. Nice working.
(defun add (number)
  	(intern (format nil "*~a" number)))

(defun myfunc (x)
	(cond ((null x) nil)
		((< (car x) 0) (cons (add (car x)) (myfunc (cdr x))))
		(T (cons (car x) (myfunc (cdr x))))))
Thanks

Now the question can lisp differ even and odd numbers? And how can the function above be modified to use with lambda?

Re: Replacing elements in a list

Lispoman wrote:
(defun add (number)
  (intern (format nil "*~a" number)))

(defun myfunc (x)
  (cond ((null x) nil)
        ((< (car x) 0) (cons (add (car x)) (myfunc (cdr x))))
        (T (cons (car x) (myfunc (cdr x))))))
Why so recursive?
Lispoman wrote:Now the question can lisp differ even and odd numbers? And how can the function above be modified to use with lambda?
You can use EVENP or ODDP as you prefer, or you can use MOD, as you could in any language. I don't know what you mean by modifying it to use with lambda.

Re: Replacing elements in a list

Thanks again! Solved.

Ive just ried to run this code
(defun add (number)
  (intern (format nil "*~a" number)))
in muLisp. but it retur error. I think it does not support format command. Is there a way to replace format by other code to get it work in muLisp?

Re: Replacing elements in a list

Lispoman wrote:in muLisp. but it retur error. I think it does not support format command. Is there a way to replace format by other code to get it work in muLisp?
I don't know how to do this in muLisp.

But isn't muLisp a bit... old? It predates ANSI CL, doesn't it? You should consider porting your code to CL. There is a member of Lisp-br (you can find him in comp.lang.lisp as namekuseijin) that said about 2 months ago that he was creating / created a script in scheme that transforms muLisp code into CL code (what a mess). I don't know how efficient it works, since in muLisp it is very common to do
(setq foo 30)
to create a global variable, while this is not the CL way to do it, although most times it will work. But now I am understanding the reason for your code to look so odd - at least to me, as I am used to CL :)

Re: Replacing elements in a list

After reading some philosophial and prectical books about lisp. :o After understanding some purposes of lambda functions and calls. :!: Guys! I still can't done my lamda call. I've modified a previous code :idea:
Now it looks like this
(defun myfunc (x)
	(cond ((null x) nil)
		((< (car x) 0) (cons (intern (format nil "*~a" (car x))) (myfunc (cdr x))))
		(T (cons (car x) (myfunc (cdr x))))))
Ive tried to figure a variant with lambda. I think it should be something like this
(defun myfunc1 (x)
        (let ((lam (lambda () (myfunc (cdr x))))
            (cond ((null x) nil)
              ((evenp (car x)) (cons (funcall lam)))
               (T (cons (car x) (funcall lam))))
But its still just abstract thoughts. :roll:

Re: Replacing elements in a list

Lispoman wrote:
(defun myfunc1 (x)
        (let ((lam (lambda () (myfunc (cdr x))))
            (cond ((null x) nil)
              ((evenp (car x)) (cons (funcall lam)))
               (T (cons (car x) (funcall lam))))
This is nuts. Try using lambda in a problem where it's actually applicable, and you'll have more luck.

Re: Replacing elements in a list

Thanks. But I need to modify this function with lambda

Re: Replacing elements in a list

I think that your problem is that you don't know what you want to do.

What I read out of your last posts is that you want to apply some function to all members of a list. This function can be either pre-defined or created "on the fly" (by using LAMBDA). There is a built-in function MAPCAR (look it up at the HyperSpec) to do exactly this.

The functions you want to use seem to be something like:
(defun mark-negative (x)
  (if (minusp x)
      (intern (format nil "*~a" x))
      x))
If you want to create this function anonymously with LAMBDA, the first line becomes "(lambda (x)", naturally.

You use MAPCAR like this:
(mapcar #'mark-negative input-list)
;; or
(mapcar (lambda (x)
          ;; ...
          )
        input-list)
"Just throw more hardware at it" is the root of all evil.
Svante

Re: Replacing elements in a list

Yeea! Solved. Nice working.

Code: Select all
(defun add (number)
(intern (format nil "*~a" number)))

(defun myfunc (x)
(cond ((null x) nil)
((< (car x) 0) (cons (add (car x)) (myfunc (cdr x))))
(T (cons (car x) (myfunc (cdr x))))))


Thanks

Now the question can lisp differ even and odd numbers? And how can the function above be modified to use with lambda?
Try oddp and evenp.
What exactly do you want to be modified? If you want to remove add definition just replace it with (lambda (number) (intern (format nil "*~a" number)))

bobi

Re: Replacing elements in a list

Thanks but I've already combined two functions in a single one
(defun myfunc (x)
   (cond ((null x) nil)
      ((< (car x) 0) (cons (intern (format nil "*~a" (car x))) (myfunc (cdr x))))
      (T (cons (car x) (myfunc (cdr x))))))
And now I need to modify this function with lambda.

Re: Replacing elements in a list

Lispoman wrote:Thanks but I've already combined two functions in a single one
(defun myfunc (x)
   (cond ((null x) nil)
      ((< (car x) 0) (cons (intern (format nil "*~a" (car x))) (myfunc (cdr x))))
      (T (cons (car x) (myfunc (cdr x))))))
And now I need to modify this function with lambda.
Why? Is this homework? I think you may have misunderstood the assignment.

Re: Replacing elements in a list

Nope I say it again... It isnt homework

Re: Replacing elements in a list

Lispoman wrote:Nope I say it again... It isnt homework
Then why in the world are you so obsessed with this? LAMBDA isn't something you just “modify a function with” — what you say you want to do makes absolutely no sense that I can see. :| Could you describe the intended effect of this modification in more detail?

Re: Replacing elements in a list

Lispoman wrote:Nope I say it again... It isnt homework
The reason people here is thinking that this is homework is that no one is understanding what exactly you want, what you are saying makes no sense. When someone say something that makes no sense it usually means that that person got an exercise wrong.

Perhaps what you want is to use mapcar to avoid recursion?
(defun myfunc (x)
  (mapcar (lambda (elt)
            (if (< elt 0)
                (intern (format nil "*~a" elt))
                elt))
          x))