# Question about ReplacePart

This is a question about ReplacePart but if there's a better that's great.

If I have a list

a= {1,2,3,4,5}


and I want to replace elements 1,3,5 with elements a,b,c from list {a,b,c}, can I use ReplaceParts to do this in one step?

I have only been able to do this replacing one element at a time.

Thanks.

• list /. {1 -> a, 3 -> b, 5 -> c} Commented Dec 31, 2014 at 9:18
• @Hubble07: You are saying that if the first list contains 1000 elements and the second list contains 500 that I would have to type 1->a, etc. 500 times? Commented Dec 31, 2014 at 9:45
• Isn't there some way to use a list of indices and replacement elements and do this all at once? Commented Dec 31, 2014 at 9:54
• you have names conflict, a is a list and an element of the last list. p.s. does this work for you: list /. Thread[{1,2,3}->{a,b,c}]?
– Kuba
Commented Dec 31, 2014 at 9:57
• for this specific case you can use a[[;; ;; 2]]= {aa,b,c}. I have changed a to aa because of name conflict as kuba mentioned. Commented Dec 31, 2014 at 10:09

I would suggest not using ReplacePart but Part assignment or Riffle instead.

Three functions to compare:

repOdd1[old_, new_] := ReplacePart[old, Thread[Range[1, Length@old, 2] -> new]]

repOdd2[old_, new_] := Module[{x = old}, x[[;; ;; 2]] = new; x]

repOdd3[old_, new_] := Riffle[new, old[[2 ;; ;; 2]]]


Test:

a = Range@9;
b = {q, r, s, t, u};

repOdd1[a, b]
repOdd2[a, b]
repOdd3[a, b]

{q, 2, r, 4, s, 6, t, 8, u}

{q, 2, r, 4, s, 6, t, 8, u}

{q, 2, r, 4, s, 6, t, 8, u}


Performance:

a = Range@999999;
b = Range[1000001, 1500000];

repOdd1[a, b] // AbsoluteTiming // First
repOdd2[a, b] // AbsoluteTiming // First
repOdd3[a, b] // AbsoluteTiming // First

1.052060

0.002000

0.008001


Both Part and Riffle are orders of magnitude faster than ReplacePart. Part assignment is a bit more verbose than Riffle if we include Module but also faster and applicable for in-place modification should that be desired.

Part also works for an arbitrary index list, not only an evenly spaced Span:

(* in-place modification in this example *)

a = Range@9;
b = {q, r, s, t, u};
a[[{1, 2, 9, 7, 5}]] = b;
a

{q, r, 3, 4, u, 6, t, 8, s}


I am a fan of using Part for many operations: Elegant operations on matrix rows and columns

• Kuba has not posted his/her answer--what do you think of that suggestion, out of curiosity? Commented Dec 31, 2014 at 11:09
• @daniel By my interpretation of the question that is not a solution. I am assuming that the list elements 1, 2, 3, are arbitrary, not always natural numbers 1..n. Commented Dec 31, 2014 at 11:11
• With that in mind I will accept yours as the more general solution, although because my lists are almost always of numbers Kuba's response was helpful. Commented Dec 31, 2014 at 11:16
• @daniel If you wish to replace by index it will be faster to do that using Part assignment. However if you wish to replace elements by pattern, which is what Kuba's code does, it is not applicable. These are two different operations with only one intersection: the case where the starting list is Range[ n ]. Commented Dec 31, 2014 at 11:20

ReplacePart[{1, 2, 3, 4, 5}, Thread[{1, 3, 5} -> {a, b, c}]]


or in general

replaceParts[original_, positions_, replacements_] := ReplacePart[
original,
]

• Assuming it works, doesn't add a step? Basically in Kuba's note it's just "Thread." Very economical. But if it works, fine.+1 Commented Dec 31, 2014 at 10:44
• No. There are two steps in both my example is: ReplacePart[{1, 2, 3, 4, 5}, Thread[{1, 3, 5} -> {a, b, c}]], while Kuba's is ReplaceAll[{1, 2, 3, 4, 5}, Thread[{1, 3, 5} -> {a, b, c}]]. Secondly Kuba's only works if the original list is a Range, mine works with any list. Commented Dec 31, 2014 at 16:32
• Inner[Rule,{1,3,5},{a,b,c}] should be faster than Thread[{1, 3, 5} -> {a, b, c}], if speed is a consideration. Commented Sep 28, 2016 at 21:00

I prefer other answers (particularly Part if the application permits it), but I will take this opportunity to mention the undocumented four-argument form of ReplacePart:

ReplacePart[{1, 2, 3, 4, 5}, {a, b, c}, {{1}, {3}, {5}} , {{1}, {2}, {3}}]
(* {a,2,b,4,c} *)


This syntax says to replace parts 1, 3, and 5 of {1, 2, 3, 4, 5} with parts 1, 2, and 3 of {a, b, c}. This syntax has been supported for a very long time, but it is undocumented so I suppose it could disappear some day.

Incidentally, and not relevant to the present question, there is also an undocumented three-argument form:

ReplacePart[{1, 2, 3, 4, 5}, {a, b, c}, {{1}, {3}, {5}}]
(* {{a,b,c},2,{a,b,c},4,{a,b,c}} *)


This form says to replace parts 1, 3, and 5 of {1, 2, 3, 4, 5} with the value {a, b, c}.

• I almost posted this myself but I could not see how it simplified the problem so I did not. You were probably the one I learned it from. Is this posted elsewhere on site? Commented Dec 31, 2014 at 23:57
• @Mr.Wizard I posted here because it is vaguely relevant and I haven't seen it mentioned elsewhere on the site. There are more posts that use ReplacePart than I care to review, so it might be out there somewhere. I'm pretty sure I've discussed it before somewhere in the StackExchange universe, but it would have been in chat or a comment. Commented Jan 1, 2015 at 0:46
• One reference: (17344). Anyway +1 for taking the time to remind us of this nugget even it if doesn't fit perfectly. Commented Jan 1, 2015 at 6:04
ReplacePart[{1, 2, 3, 4, 5}, {i_?OddQ} :> {a, b, c}[[(i + 1)/2]]]


{a, 2, b, 4, c}

With data from the accepted answer

a = Range @ 9;

b = {q, r, s, t, u};


Using SubsetMap (new in 12.0)

SubsetMap[b &, a, a[[;; ;; 2]]]


{q, 2, r, 4, s, 6, t, 8, u}