在Python中倒序柯里化

6

Suppose I have a function like this:

from toolz.curried import *

@curry
def foo(x, y):
    print(x, y)

然后我可以调用:
foo(1,2)
foo(1)(2)

两者都按预期返回相同的结果。

然而,我想做类似于这样的事情:

@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。然而,该函数是预配置的,并返回一个仅接受DataFrame的函数,类似于装饰器。可以使用以下方式实现相同的行为:
def filter_columns(*args):
    def f(df):
        return df[[*args]]
    return f

然而,我总是必须运行两个函数调用,例如:filter_columns()(df),我希望避免这种情况。


你使用的是哪个版本的Python? - amirouche
所以对于 foo(1,2)foo(1)(2),您希望它打印出 2 1 吗? - Copperfield
@amirouche Python 3.5.1 - Xiphias
你能给出一个更具有说明性的行为期望的例子吗? - Copperfield
1
哦,对了,这个管道来自那个 import *,它们总是让我很烦恼,因为我不知道我有什么... 让我重新考虑一下我的答案,使用新的更新。 - Copperfield
显示剩余2条评论
1个回答

2

很遗憾,我对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")
)

好的,我看到这个可以使用你的pipe定义;然而,当我使用来自toolz的管道时,我遇到了困难。 - Xiphias
1
太棒了!我没有想过 df,columns = argv[-1],argv[:-1]。多么简单而优雅! - Xiphias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接