如果给定一个函数一个列表,则自动使用list comprehension/map()递归 [英] Automatically use list comprehension/map() recursion if a function is given a list
问题描述
作为Mathematica用户,我喜欢自动遍历列表"的函数(如Mathematica人们所说的那样-请参见 http://reference.wolfram.com/mathematica/ref/Listable.html ).这意味着,如果给一个函数一个列表而不是一个值,它将自动使用每个列表条目作为参数并返回结果列表-例如
As a Mathematica user, I like functions that automatically "threads over lists" (as the Mathematica people call it - see http://reference.wolfram.com/mathematica/ref/Listable.html). That means that if a function is given a list instead of a single value, it automatically uses each list entry as an argument and returns a list of the results - e.g.
myfunc([1,2,3,4]) -> [myfunc(1),myfunc(2),myfunc(3),myfunc(4)]
我在Python中实现了以下原则:
I implemented this principle in Python like this:
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 it? Can you think of any downsides of this implementation or the strategy overall?
推荐答案
如果您要在许多函数中执行此操作,则可以使用Python装饰器.这是一个简单但有用的方法.
If this is something you're going to do in a lot of functions, you could use a Python decorator. Here's a simple but useful one.
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
这样,只需在函数之前添加行@threads_over_lists
即可使其表现为这种方式.例如:
This way, just adding the line @threads_over_lists
before your function would make it behave this way. For example:
@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)
您还应该考虑是否要对列表或其他可迭代对象(如元组和生成器)进行矢量化处理. 这是一个有用的StackOverflow问题确定这一点.不过要小心-字符串是可迭代的,但是您可能不希望函数对其中的每个字符进行操作.
You should also consider whether you want this to vectorize only over lists, or also over other iterable objects like tuples and generators. This is a useful StackOverflow question for determining that. Be careful, though- a string is iterable, but you probably won't want your function operating on each character within it.
这篇关于如果给定一个函数一个列表,则自动使用list comprehension/map()递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!