在 python 中以倒序柯里化
Currying in inversed order in python
假设我有这样一个函数:
from toolz.curried import *
@curry
def foo(x, y):
print(x, y)
然后我可以打电话:
foo(1,2)
foo(1)(2)
两者return与预期相同。
但是,我想做这样的事情:
@curry.inverse # hypothetical
def bar(*args, last):
print(*args, last)
bar(1,2,3)(last)
这背后的想法是,我想预先配置一个函数,然后将其放入管道中,如下所示:
pipe(data,
f1, # another function
bar(1,2,3) # unknown number of arguments
)
然后,bar(1,2,3)(data)
将作为管道的一部分被调用。但是,我不知道该怎么做。有任何想法吗?非常感谢!
编辑:
要求提供更具说明性的示例。于是,它来了:
import pandas as pd
from toolz.curried import *
df = pd.DataFrame(data)
def filter_columns(*args, df):
return df[[*args]]
pipe(df,
transformation_1,
transformation_2,
filter_columns("date", "temperature")
)
如您所见,DataFrame 是通过函数传递的,filter_columns
就是其中之一。但是,该函数是预先配置的,return 是一个只接受 DataFrame 的函数,类似于装饰器。可以用这个实现相同的行为:
def filter_columns(*args):
def f(df):
return df[[*args]]
return f
但是,我总是需要 运行 打两次电话,例如filter_columns()(df)
,这是我想避免的。
好吧,我不熟悉 toolz 模块,但看起来没有简单的方法来柯里化具有任意数量参数的函数,所以让我们尝试其他方法。
首先作为
的替代品
def filter_columns(*args):
def f(df):
return df[*args]
return f
(顺便说一下,df[*args]
是语法错误)
为了避免 filter_columns()(data)
你可以只抓取 args
中的最后一个元素并使用切片符号来抓取其他所有元素,例如
def filter_columns(*argv):
df, columns = argv[-1], argv[:-1]
return df[columns]
并用作 filter_columns(df)
、filter_columns("date", "temperature", df)
等
然后使用 functools.partial
构建新的、部分应用良好的过滤器来构建管道,例如
from functools import partial
from toolz.curried import pipe # always be explicit with your import, the last thing you want is import something you don't want to, that overwrite something else you use
pipe(df,
transformation_1,
transformation_2,
partial(filter_columns, "date", "temperature")
)
假设我有这样一个函数:
from toolz.curried import *
@curry
def foo(x, y):
print(x, y)
然后我可以打电话:
foo(1,2)
foo(1)(2)
两者return与预期相同。
但是,我想做这样的事情:
@curry.inverse # hypothetical
def bar(*args, last):
print(*args, last)
bar(1,2,3)(last)
这背后的想法是,我想预先配置一个函数,然后将其放入管道中,如下所示:
pipe(data,
f1, # another function
bar(1,2,3) # unknown number of arguments
)
然后,bar(1,2,3)(data)
将作为管道的一部分被调用。但是,我不知道该怎么做。有任何想法吗?非常感谢!
编辑:
要求提供更具说明性的示例。于是,它来了:
import pandas as pd
from toolz.curried import *
df = pd.DataFrame(data)
def filter_columns(*args, df):
return df[[*args]]
pipe(df,
transformation_1,
transformation_2,
filter_columns("date", "temperature")
)
如您所见,DataFrame 是通过函数传递的,filter_columns
就是其中之一。但是,该函数是预先配置的,return 是一个只接受 DataFrame 的函数,类似于装饰器。可以用这个实现相同的行为:
def filter_columns(*args):
def f(df):
return df[[*args]]
return f
但是,我总是需要 运行 打两次电话,例如filter_columns()(df)
,这是我想避免的。
好吧,我不熟悉 toolz 模块,但看起来没有简单的方法来柯里化具有任意数量参数的函数,所以让我们尝试其他方法。
首先作为
的替代品def filter_columns(*args):
def f(df):
return df[*args]
return f
(顺便说一下,df[*args]
是语法错误)
为了避免 filter_columns()(data)
你可以只抓取 args
中的最后一个元素并使用切片符号来抓取其他所有元素,例如
def filter_columns(*argv):
df, columns = argv[-1], argv[:-1]
return df[columns]
并用作 filter_columns(df)
、filter_columns("date", "temperature", df)
等
然后使用 functools.partial
构建新的、部分应用良好的过滤器来构建管道,例如
from functools import partial
from toolz.curried import pipe # always be explicit with your import, the last thing you want is import something you don't want to, that overwrite something else you use
pipe(df,
transformation_1,
transformation_2,
partial(filter_columns, "date", "temperature")
)