I have a list A=[a,b,c,d]
. I need to calculate a new list B
based on operations between each item in A
.
B= [a, b-(a), c-(a (b-a)), d-(a (b-a) (c-(a (b-a)))) ]
Is there a Pythonic way of doing this? List A is not always a 4 item list, so the solution needs to be generalizable to lists of arbitrary length. Thanks in advance.
CodePudding user response:
All your terms cancel out (c-(a (b-a))
simplifies to c - b
, d-(a (b-a) (c-(a (b-a))))
simplifies to d - c
), so the real algorithm here is that each term is equal to the matching term minus the prior term. This simplifies things dramatically:
B = [A[0]] # Initial term has no prior to subtract from it
B = [x - y for x, y in zip(A[1:], A)] # All other terms computed by subtracting term n - 1 from term n
If you want to one-line this (ignoring imports) you can stick a virtual 0
in to get the results for the first element without explicitly special-casing it:
from itertools import chain # At top of file
B = [x - y for x, y in zip(A, chain([0], A))]
If you love using map
and friends for microoptimizations, you could replace the latter with:
from operator import sub # At top of file
B = [*map(sub, A, chain([0], A))]
and push all the work to the C layer (no per-element bytecode execution).
CodePudding user response:
Observe that the expression for your list can be simplified to:
B = [a, b-a, c-b, d-c]
With this in mind, we can use a list comprehension:
[y - x for x, y in zip([0] data, data)]
For example,
data = [1, 2, 7, 6]
result = [y - x for x, y in zip([0] data, data)]
print(result)
outputs:
[1, 1, 5, -1]
CodePudding user response:
As suggest by the guys on the comments, this is the simplest and fastest solution:
A = [5, 9, 3, 8]
B = [x - y for x, y in zip(A, [0] A)]
This outputs:
B
[5, 4, -6, 5]
CodePudding user response:
Pythonic way:-
A = [1,2,3,4]
B = [A[0]] [A[i 1]-A[i] for i in range(len(A)-1)]