11
$\begingroup$

Say I have two lists of pairs:

a = {{1, 2}, {3, 4}};
b = {{5, 6}, {7, 8}};

And I want to add the second element of every pair in b to the second element of every pair in a, so the expected result would be {{1, 8}, {3, 12}}.

How can I do this?

$\endgroup$
9
$\begingroup$
lst1 = {{1, 2}, {2, 4}};

lst1a = lst1;
lst1a[[All, 2]] *= 2;
lst1a

{{1, 4}, {2, 8}}

lst2 = {{3, 5}, {10, 2}};

lst1b = lst1;
lst1b[[All, 2]] += lst2[[All, 2]];
lst1b

{{1, 7}, {2, 6}}

ClearAll[f1]
f1 = Module[{l = #}, l[[;; , 2]] += #2[[;; , 2]]; l] &;

f1[lst1, lst1]

{{1, 4}, {2, 8}}

f1[lst1, lst2]

{{1, 7}, {2, 6}}

f1[a, b] (* a and b from m_goldberg's answer *)

{{1, 10}, {3, 14}, {5, 18}}

Also

ClearAll[f2]
f2 = Module[{l2 = #2}, l2[[All, 1]] = 0; # + l2] &;

{f1[lst1, lst1] == f2[lst1, lst1], f1[lst1, lst2] == f2[lst1, lst2], f1[a, b] == f2[a, b]}

{True, True, True}

$\endgroup$
10
$\begingroup$

I like to do this kind of thing by writing a custom function to perform the the desired operation on two given pairs. I then map this function over the two lists with MapThread. In most cases, by using Mathematica's argument-pattern destructuring, the custom function can be expressed extremely simply. This is one of those cases.

The custom function is

f[{x_, y_}, {_, z_}] := {x, y + z}

Note that the righthand side is a literal expression of the desired result.

Now let's contrive some test data. I write the generator so that two lists of pairs can easily be given any length.

With[{n = 3}, {a, b} = Partition[Partition[Range[4 n], 2], n]];
a
b
{{1, 2}, {3, 4}, {5, 6}}
{{7, 8}, {9, 10}, {11, 12}}

Now we MapThread the function f over a and b.

MapThread[f, {a, b}]

{1, 10}, {3, 14}, {5, 18}}

$\endgroup$
  • 1
    $\begingroup$ +1 to how you worded this, I enjoyed being able to read and follow along with what you did! Going to show this to my first class of wolfram recruits tomorrow :)) $\endgroup$ – CA Trevillian Oct 4 at 3:40
4
$\begingroup$

Try this:

{{1, 2}, {2, 4}} + ({{1, 2}, {2, 4}} /. {x_,y _} -> {0, y})

(* {{2, 4}, {4, 8}}  *)

or this

(# + (# /. {x_, y_} -> {0, y})) &[{{1, 2}, {2, 4}}]

(* {{1, 2}, {4, 8}}  *)

Have fun!

$\endgroup$
4
$\begingroup$
list = {{1, 2}, {2, 4}};

MapAt[2 # &, {All, 2}] @ list

{{1, 4}, {2, 8}}

$\endgroup$
  • 1
    $\begingroup$ Hi @eldo! It's been a while... :) $\endgroup$ – Michael E2 Oct 3 at 19:39
  • $\begingroup$ Yes, nice to see you again :} $\endgroup$ – eldo Oct 3 at 19:41
4
$\begingroup$
list1 = {{1, 2}, {2, 4}};

Adding the second elements from each pair of the same list:

{#[[1]], 2 #[[2]]} & /@ list1

{{1, 4}, {2, 8}}

Adding the second element from a different list:

list2 = {{a, b}, {c, d}};
{#[[1, 1]], #[[1, 2]] + #[[2, 2]]} & /@ Transpose[{list1, list2}]

{{1, 2 + b}, {2, 4 + d}}

$\endgroup$
4
$\begingroup$

In situations like this, Dot can be useful

a + b.{{0,0},{0,1}}

{{1, 8}, {3, 12}}

ga={{1, 2}, {3, 4}, {5, 6}}
gb={{7, 8}, {9, 10}, {11, 12}}

ga + gb.{{0,0},{0,1}}

{{1, 10}, {3, 14}, {5, 18}}

$\endgroup$
3
$\begingroup$
lst = {{1, 2}, {2, 4}};
MapThread[{First[#1], Last[#1] + Last[#2]} &, {lst, lst}]

{{1, 4}, {2, 8}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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