[英]Automatically use list comprehension/map() recursion if a function is given a list
作為Mathematica用戶,我喜歡自動“遍歷列表”的函數(正如Mathematica所稱的那樣 - 請參閱http://reference.wolfram.com/mathematica/ref/Listable.html )。 這意味着如果函數被賦予列表而不是單個值,它會自動使用每個列表條目作為參數並返回結果列表 - 例如
myfunc([1,2,3,4]) -> [myfunc(1),myfunc(2),myfunc(3),myfunc(4)]
我在Python中實現了這個原則,如下所示:
def myfunc(x):
if isinstance(x,list):
return [myfunc(thisx) for thisx in x]
#rest of the function
這是一個很好的方法嗎? 你能想到這個實施或整體戰略的任何缺點嗎?
如果您要在很多函數中執行此操作,則可以使用Python裝飾器。 這是一個簡單但有用的。
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
行就可以使它以這種方式運行。 例如:
@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問題,用於確定它。 但要小心 - 字符串是可迭代的,但您可能不希望函數對其中的每個字符進行操作。
這是一個很好的方法。 但是,您必須為您編寫的每個函數執行此操作。 為了避免這種情況,你可以使用像這樣的裝飾器 :
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]))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.