Two solutions that don't assume that things "cancel out" (because that is wrong already for standard types like float and Counter, as shown below).
If I understand the pattern correctly, the first B-value shall be the first A-value and then each next B-value shall always be the next A-value minus the sum of all previous B-values. One way to do that:
B = []
for a in A:
if not B:
b = sumB = a
else:
b = a - sumB
sumB = sumB + b
B.append(b)
Fun one using itertools.accumulate and operator.sub:
B = A[:1]
B += map(sub, A[1:], accumulate(B))
Tests:
A = [31, 41, 59, 26]
reference [31, 10, 18, -33]
subtract_neighbors correct [31, 10, 18, -33]
loop correct [31, 10, 18, -33]
fun correct [31, 10, 18, -33]
A = [1, 1, 1e-20, 1e-20]
reference [1, 0, -1.0, 1e-20]
subtract_neighbors wrong [1, 0, -1.0, 0.0]
loop correct [1, 0, -1.0, 1e-20]
fun correct [1, 0, -1.0, 1e-20]
A = [Counter(), Counter({None: 1}), Counter(), Counter({None: 1})]
reference [Counter(), Counter({None: 1}), Counter(), Counter()]
subtract_neighbors wrong [Counter(), Counter({None: 1}), Counter(), Counter({None: 1})]
loop correct [Counter(), Counter({None: 1}), Counter(), Counter()]
fun correct [Counter(), Counter({None: 1}), Counter(), Counter()]
Code doing the above checks (Try it online!):
def reference(A):
a, b, c, d = A
return [a, b-(a), c-(a+(b-a)), d-(a+(b-a)+(c-(a+(b-a)))) ]
def subtract_neighbors(A):
a, b, c, d = A
return [a, b-a, c-b, d-c]
def loop(A):
B = []
for a in A:
if not B:
b = sumB = a
else:
b = a - sumB
sumB = sumB + b
B.append(b)
return B
def fun(A):
B = A[:1]
B += map(sub, A[1:], accumulate(B))
return B
from collections import Counter
from itertools import accumulate
from operator import sub
funcs = [
reference,
subtract_neighbors,
loop,
fun,
]
tests = [
[31, 41, 59,26],
[1, 1, 1e-20, 1e-20],
[Counter(), Counter([None])] * 2,
]
for A in tests:
print(' A =', A)
for func in funcs:
result = func(A)
if func is reference:
expect = result
correctness = ' '
else:
correctness = 'correct' if result == expect else 'wrong '
print(f'{func.__name__:19}', correctness, result)
print()