В Mathematica, какой самый чистый способ взять список
{r1, r2, r3, ..., rn, a, b}
и вернуть
{r1, r2, r3, ..., rn, a + b}
или в более общем смысле
{r1, r2, r3, ..., rn, f[a, b]}
для некоторой функцииf
f
lst = {a[1], a[2], a[3], a[4], a[5], a[6], a[7], a, b}; lst /. {a___, b_, c_} -> {a, f[b, c]} ==> {a[1], a[2], a[3], a[4], a[5], a[6], a[7], f[a, b]}
или (безобразно):
Append[Take[lst, {1, -3}], f @@ lst[[{-2, -1}]]]
Я бы использовал правила, если производительность не является большой проблемой (списки не упакованы и т. Д.):
lst = {a, b, c, d, e} In[13]:= Replace[lst, {left__, ntl_, l_} :> {left, f[ntl, l]}, {0}] Out[13]= {a, b, c, f[d, e]}
Вот мое мнение:
addLastTwo = Function[Append[Drop[#, -2], Total[Take[#, -2]]]]; In[225]:= addLastTwo[{r1, r2, r3, r4, r5}] Out[225]= {r1, r2, r3, r4 + r5}
Это немного быстрее, чем решение Mr.Wizard, хотя и менее общее:
In[226]:= Do[addLastTwo@a, {10000}] // Timing Out[226]= {0.25, Null} In[227]:= Do[combineLast[a, Plus], {10000}] // Timing Out[227]= {0.39, Null}
Предположим, 'список' определен:
Remove[list]; list = {r1, r2, r2, r4, r5, a, b};
Переустановите 'список' в {r1, r2, r3, r4, r5, a}, заменив [[-1]] насумма двух последних элементов в списке.
list = ReplacePart[Drop[list, -1], -1 -> Plus @@ list[[-2 ;; -1]]]
Спасибо за вопрос, кстати.:)
Если бы я не догадался, Саймон, я бы первым ответил. Гайки. В любом случае, вот мой поздний ответ.
combineLast = Module[{x = #}, x[[-2]] = #2 @@ x[[-2 ;;]]; Most[x] ] &;
Сравнение:
leoCL[lst_, f_] := Replace[lst, {left__, ntl_, l_} :> {left, f[ntl, l]}, {0}] a = RandomInteger[1*^9, 5000]; Do[combineLast[a, Plus], {5000}] // Timing Do[leoCL[a, Plus], {5000}] // Timing
{0.078, Null} {1.844, Null}