Reputation: 545
If I define a function as:
def somefunc(a, b, c):
out = [ (a+b)/c for a, b, c in zip(a, b, c) ]
return out
all the arguments must be lists of the same length, otherwise I would get the output truncated. Example: somefunc([1, 2], [3, 4], [5, 5])
would give me [0.8, 1.2]
.
It would be really convenient to be able to input a single number instead of a list when it doesn't change, like: somefunc([1, 2], [3, 4], 5)
. Of course any of the arguments can be reduced to a single value instead of a list. This can be achieved using numpy with this function definition:
from numpy import array
def somefunc(a, b, c):
a=array(a)
b=array(b)
c=array(c)
out = (a+b)/c
return out
Is there a way to do the same without numpy (and without converting all the arguments one by one)?
Upvotes: 0
Views: 650
Reputation: 64328
Numpy is awesome, and is perfect for vectorizing computaions like the one you posted. I'd recommend you do use it.
Also, you don't need to convert all the arguments to arrays, only one, and it is better to use asarray
, which would avoid creating a new copy when one isn't necessary.
def somefunc(a, b, c):
return (asarray(a) + b) / c
Upvotes: 1
Reputation: 11322
Sure, you can make an infinite list repeating any argument that is not a list in itself.
from itertools import repeat
def broadcast(o):
return o if hasattr(o, '__iter__') else repeat(o)
def somefunc(a, b, c):
out = [ (a+b)/c for a, b, c in zip(broadcast(a), broadcast(b), broadcast(c)) ]
return out
>>> somefunc([1, 2], [3, 4], 5)
[0.8, 1.2]
>>> somefunc([1, 2], 5, [3, 4])
[2.0, 1.75]
>>>
Upvotes: 2