Use recursion list comprehension / map () automatically if a list is assigned to a function

As a user of Mathematica, I like functions that automatically "flow through lists" (according to Mathematica people - see http://reference.wolfram.com/mathematica/ref/Listable.html ), This means that if a function is assigned a list instead of a single value, it automatically uses each record as an argument and returns a list of results - for example,

myfunc([1,2,3,4]) -> [myfunc(1),myfunc(2),myfunc(3),myfunc(4)] 

I implemented this principle in Python as follows:

 def myfunc(x): if isinstance(x,list): return [myfunc(thisx) for thisx in x] #rest of the function 

Is this a good way to do this? Can you come up with any flaws in this implementation or the strategy as a whole?

+4
source share
2 answers

If this is what you are going to do in a lot of functions, you can use the Python decorator. Here is simple but useful.

 def threads_over_lists(fn): def wrapped(x, *args, **kwargs): if isinstance(x, list): return [fn(e, *args, **kwargs) for e in x] return fn(x, *args, **kwargs) return wrapped 

This way, just adding the @threads_over_lists line before your function forces it to behave that way. For instance:

 @threads_over_lists def add_1(val): return val + 1 print add_1(10) print add_1([10, 15, 20]) # if there are multiple arguments, threads only over the first element, # keeping others the same @threads_over_lists def add_2_numbers(x, y): return x + y print add_2_numbers(1, 10) print add_2_numbers([1, 2, 3], 10) 

You should also consider whether you want this to be vectorized only over lists, as well as over other iterable objects such as tuples and generators. This is a useful StackOverflow question for defining it. However, be careful - the string is repeatable, but you probably won't want your function to work on every character inside it.

+7
source

This is a good way to do it. However, you will have to do this for every function you write. To avoid this, you can use a decorator like this:

 def threads(fun): def wrapper(element_or_list): if isinstance(element_or_list, list): return [fun(element) for element in element_or_list] else: return fun(element_or_list) return wrapper @threads def plusone(e): return e + 1 print(plusone(1)) print(plusone([1, 2, 3])) 
+3
source

All Articles