7
$\begingroup$

I have a list like this l = {1 + 2*s, 2 + 3*s, 4 + 1*s}, and I have calculated s = {1, 2, 3}. I need to replace s in l so that l = {1 + 2*1, 2 + 3*2, 4 + 1*3}. Is it possible to do that with ReplacAll (/.) and Rule?

$\endgroup$
3
  • $\begingroup$ Did one of the answers below answer your question? If so, please accept it! $\endgroup$
    – march
    Jan 31, 2016 at 6:06
  • 1
    $\begingroup$ Somewhat related: (3858) $\endgroup$
    – Mr.Wizard
    Jan 31, 2016 at 7:15
  • $\begingroup$ @Developer2000, is the idea of your question to avoid other structural constructs except /.? $\endgroup$
    – garej
    Jan 31, 2016 at 7:42

6 Answers 6

10
$\begingroup$

Here's some ways. Using:

l = {1+2*s,2+3*s,4+1*s};
slist = {1, 2, 3};

The answer closest to what you asked is

{1 + 2*s, 2 + 3*s, 4 + 1*s} /. s -> slist // Diagonal

However, that does 3^2 - 3 too many calculations, so here's some more ways.

Module[{i = 1}, l /. s :> slist[[i++]]]
MapThread[#1 /. s -> #2 &, {l, slist}]
MapThread[ReplaceAll, {l, Thread[s -> slist]}]
ReplaceAll @@@ Transpose[{l, Thread[s -> slist]}]
Map[First@#1 /. s -> Last@#1 &, Transpose@{l, slist}]
MapIndexed[#1 /. s -> slist[[First@#2]] &, l]

If s is always going to be the list {1, 2, 3, ...}, then:

MapIndexed[#1 /. s -> First@#2 &, l]
$\endgroup$
3
  • 2
    $\begingroup$ Hey, you even got the one with Diagonal! Nice work. You could avoid the extraneous computations I believe by using Diagonal[l /. List /@ Thread[s -> slist]] though I admit that is sadly not so pretty. $\endgroup$
    – Mr.Wizard
    Jan 31, 2016 at 7:09
  • $\begingroup$ @Mr.Wizard. And I feel like I'm still missing some that are actually different in nature to those above (practically all of these rely on the same idea). My favorite is the PostIncrement one, though; one of my favorite slick tricks (that I learned here somewhere along the way). $\endgroup$
    – march
    Jan 31, 2016 at 7:15
  • 2
    $\begingroup$ If I think if anything else that's not contrived I'll post it. $\endgroup$
    – Mr.Wizard
    Jan 31, 2016 at 7:19
8
$\begingroup$
list={1+2*s,2+3*s,4+1*s};

sValues={1,2,3};

Using HoldForm to see the intermediate step

Inner[HoldForm[#1 /. s -> #2]&, list, sValues, List]

(*  {1+2 s/. s->1,2+3 s/. s->2,4+s/. s->3}  *)

%//ReleaseHold

(*  {3,8,7}  *)

Without the intermediate step

Inner[#1 /. s -> #2 &, list, sValues, List]

(*  {3,8,7}  *)
$\endgroup$
1
  • 1
    $\begingroup$ I really don't get to use Inner enough. Love the use of Inner for this problem. $\endgroup$
    – march
    Sep 25, 2015 at 17:19
4
$\begingroup$
l = {1 + 2*s, 2 + 3*s, 4 + 1*s};
slist = {1, 2, 3};

SubsetMap

SubsetMap[slist &, Position[l, s]] @ l
{3, 8, 7}

ReplaceAll

l /. s :> Last[slist = RotateLeft[slist]]
{3, 8, 7}
$\endgroup$
1
  • $\begingroup$ +1 - a very useful (undocumented?) use of SubsetMap $\endgroup$
    – eldo
    Dec 30, 2023 at 8:34
3
$\begingroup$
a = {1 + 2*s, 2 + 3*s, 4 + 1*s};
b = {1, 2, 3};

ReplacePart[i_ :> (a[[i]] /. s :> b[[i]])] @ list

{3, 8, 7}

$\endgroup$
2
$\begingroup$
{#1[[1]] /. s -> #2[[1]], #1[[2]] /. s -> #2[[2]], #1[[3]] /. 
    s -> #2[[3]]} &[{1+2*s,2+3*s,4+1*s}, {1,2,3}]
$\endgroup$
2
  • $\begingroup$ Table[(#1[[i]] /. s -> #2[[i]]), {i, 3}] &[l,{1,2,3}] $\endgroup$
    – garej
    Jan 31, 2016 at 7:51
  • $\begingroup$ ReplacePart[l, Thread[Position[l, s] -> {1,2,3}] $\endgroup$
    – garej
    Jan 31, 2016 at 12:16
1
$\begingroup$

An alternative is to use MapAt and Diagonal as follows:

a = {1 + 2*s, 2 + 3*s, 4 + 1*s};
b = {1, 2, 3};

Diagonal@MapAt[b &, a, Position[a, s]]

(*{3, 8, 7}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.