Добавить второй элемент списка из другого списка, если первые элементы равны (Mathematica) - PullRequest
0 голосов
/ 04 августа 2020

У меня есть два списка b1 = {{1, 2}, {3, 4}, {4, 5}, {9, 3}, {15,2}}, b2 = {{1, 7}, {3, 6}, {8, 5}, {9, 7}}

Моя цель - добавить второй элемент в оба списка, если первые элементы равны, и сохранить элементы, различающиеся в обоих списках.

{{1,9}, {3,10}, {4,5}, {8,5}, {9,10}, {15,2}}

Ответы [ 3 ]

1 голос
/ 05 августа 2020
b1 = {{1, 2}, {3, 4}, {4, 5}, {9, 3}, {15, 2}};
b2 = {{1, 7}, {3, 6}, {8, 5}, {9, 7}};

u = Union@Join[b1, b2][[All, 1]];
Map[{#, Total[Flatten[{
       Cases[b1, {#, _}],
       Cases[b2, {#, _}]}[[All, All, -1]]]]} &, u]

{{1, 9}, {3, 10}, {4, 5}, {8, 5}, {9, 10}, {15, 2}}

или

g = GroupBy[Join[b1, b2], First -> Last];
Sort[{#1, Total[#2]} & @@@ Normal[g]]

{{1, 9}, {3, 10}, {4, 5}, {8, 5}, {9, 10}, { 15, 2}}

Или просто

Sort[Normal[GroupBy[Join[b1, b2], First -> Last, Total]] /. Rule -> List]
1 голос
/ 05 августа 2020

Это может понравиться

Sort[Join[b1, b2]] //. {a:___, {m_, n_}, {m_, p_}, z:___} :> {a, {m, n + p}, z}

Не очень тщательно протестировано.

0 голосов
/ 05 августа 2020

Если бы ваши два списка были одинаковой длины, вы могли бы использовать Thread для объединения аргументов. Затем вы можете написать функцию для проверки каждой пары, чтобы решить, что с ними делать. Это будет работать нормально, за исключением того, что вы не хотите изменять два аргумента, если первые элементы не совпадают. Чтобы решить эту проблему, вы можете использовать трюк с последовательностью.

b1={{1,2},{3,4},{4,5},{9,3}}; b2={{1,7},{3,6},{8,5},{9,7}};
f[{a_,b_},{c_,d_}]:=If[a==c,{a,b+d},Sequence@@{{a,b},{c,d}}];
Thread[f[b1,b2]]

Все, что возвращает

{{1,9},{3,10},{4,5},{8,5},{9,10}}

Это точно верно для каждой пары списков одинаковой длины?

НО вы отредактировали свой вопрос, чтобы разрешить списки неравной длины. Thread не будет работать с этим. Но, возможно, вы можете написать функцию, которая будет использоваться поверх этого. Он проверит, равны ли длины списков, если да, то сделайте то, что было показано, если нет, то обрежьте более длинный список, используйте то, что было показано, и, наконец, добавьте дополнительный элемент из более длинного списка.

Вы можете придумать, как это сделать?

...