簡體   English   中英

如果為函數指定了列表,則自動使用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 )。 這意味着如果函數被賦予列表而不是單個值,它會自動使用每個列表條目作為參數並返回結果列表 - 例如

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM