问题
I want to perform element-wise mathematical operations (e.g. sum, multiply..) on two Python lists containing numbers or multiple nested lists which may contain again numbers or lists and so on.
The shapes of the two lists are equal when performing the operation. Furthermore, the result should be of the same shape as the two input lists.
A shape may differ in:
length,
width (i.e. number of nestings),
order (e.g. the lists start with a number followed by a nested list, but it may also be that it starts with a nested list, followed by numbers).
The shape changes arbitrarily each time I want to perform a mathematical operation.
How can I perform math operations on arbitrarily shaped lists?
In the past, I've implemented a customized piece of code for each different shape, similar to 1, 2, 3, 4, 5, 6, 7, 8, 9, but I was wondering if there is already a more general solution in the form of a library or reference code for this.
Example 1 (summation):
a = [ 1, 2, 3, 4,[ 5, 6, 7, 8]]
b = [10,20,30,40,[50,60,70,80]]
c = elementwiseSUM(a,b)
c
would result in
[11, 22, 33, 44, [55, 66, 77, 88]]
Example 2 (summation):
d = [ 1,[ 2, 3], 4, [ 5, 6, 7], [[ 8], [ 9, 10]]]
e = [10,[20,30], 40, [50,60,70], [[80], [90,100]]]
f = elementwiseSUM(d,e)
f
would result in
[11, [22, 33], 44, [55, 66, 77], [[88], [99, 110]]]
Example 3 (multiplication):
g = [[4,2],1,1]
h = [[8,3],1,9]
i = elementwiseMUL(g,h)
i
would result in
[[32, 6], 1, 9]
elementwiseSUM()
and elementwiseMUL()
are placeholders for the library functions which I am looking for.
回答1:
Here's the solution I came up with
a = [ 1, 2, 3, 4, [ 5, 6, 7, 8]]
b = [10, 20, 30, 40, [50, 60, 70, 80]]
def element_wise(a, b, f):
return [element_wise(i, j, f) if type(i) == list and type(j) == list else f(i, j) for i, j in zip(a, b)]
c = element_wise(a, b, lambda x, y: x + y) # [11, 22, 33, 44, [55, 66, 77, 88]]
so a
and b
are your lists, and f
is the function you want to apply, as you can see I wrote a simple function to add ints
You can either write your own lambdas or just use the operator
module.
回答2:
It's not exactly taking advantage of a built-in python module (besides operator
), but how about something like this?
def element_wise(list_a, list_b, operator):
result = []
assert len(list_a) == len(list_b)
for a, b in zip(list_a, list_b):
is_lists = isinstance(a, list) and isinstance(b, list)
is_ints = isinstance(a, int) and isinstance(b, int)
if is_lists:
result.append(element_wise(a, b, operator))
elif is_ints:
result.append(operator(a, b))
else:
raise ValueError
return result
def main():
from operator import add, mul
list_sum_a = [ 1, 2, 3, 4, [ 5, 6, 7, 8]]
list_sum_b = [10, 20, 30, 40, [50, 60, 70, 80]]
list_mul_a = [[4, 2], 1, 1]
list_mul_b = [[8, 3], 1, 9]
result_sum = element_wise(list_sum_a, list_sum_b, add)
result_mul = element_wise(list_mul_a, list_mul_b, mul)
print(result_sum)
print(result_mul)
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
Output:
[11, 22, 33, 44, [55, 66, 77, 88]]
[[32, 6], 1, 9]
回答3:
Unsure about any library that has a built in method, but using one wouldn't be any faster than creating one yourself
an example that is not any kind of production code but shows an easy way to do this is:
import operator
ops = {
"+": operator.add,
"-": operator.sub,
"*": operator.mul,
"/": operator.div
}
a = [ 1,[ 2, 3], 4, [ 5, 6, 7], [[ 8], [ 9, 10]]]
b = [10,[20,30], 40, [50,60,70], [[80], [90,100]]]
def foo(x, y, op):
if type(x) == list:
return [foo(a, b, op) for a, b in zip(x, y)]
else:
return ops[op](x, y)
#Run
print foo(a, b, '+')
回答4:
I am giving the solution code for example one and three, But this solution is totally depends on your list i.e. How many list you have inside the list because i am using for loop and that depends on your list.
Example 1 (summation solution)
a = [ 1, 2, 3, 4,[ 5, 6, 7, 8]]
b = [10,20,30,40,[50,60,70,80]]
def elementwiseSUM(a, b):
pl = []
cl = []
for i, j in zip(a, b):
if type(i) and type(j) != list:
pl.append(i+j)
if type(i) and type(j) == list:
for k, l in zip(i, j):
cl.append(k+l)
pl.append(cl)
return pl
print(elementwiseSUM(a, b))
Example 2 (multiplication solution)
g = [[4,2],1,1]
h = [[8,3],1,9]
def elementwiseMUL(g, h):
pl = []
cl = []
for i, j in zip(g, h):
if type(i) and type(j) != list:
cl.append(i*j)
if type(i) and type(j) == list:
for k, l in zip(i, j):
pl.append(k*l)
pl.append(cl)
return pl
print(elementwiseMUL(g, h))
来源:https://stackoverflow.com/questions/57615420/how-to-perform-element-wise-arithmetic-operations-e-g-add-subtract-multiply