简体   繁体   English

在Python中以相反的顺序进行咖喱

[英]Currying in inversed order in python

Suppose I have a function like this: 假设我有一个像这样的函数:

from toolz.curried import *

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

Then I can call: 然后我可以打电话给:

foo(1,2)
foo(1)(2)

Both return the same as expected. 两者返回相同的预期。

However, I would like to do something like this: 但是,我想做这样的事情:

@curry.inverse # hypothetical
def bar(*args, last):
    print(*args, last)

bar(1,2,3)(last)

The idea behind this is that I would like to pre-configure a function and then put it in a pipe like this: 其背后的想法是,我想预先配置一个函数,然后将其放入这样的管道中:

pipe(data,
    f1, # another function
    bar(1,2,3) # unknown number of arguments
)

Then, bar(1,2,3)(data) would be called as a part of the pipe. 然后, bar(1,2,3)(data)将被称为管道的一部分。 However, I don't know how to do this. 但是,我不知道该怎么做。 Any ideas? 有任何想法吗? Thank you very much! 非常感谢你!

Edit: 编辑:

A more illustrative example was asked for. 要求提供一个更说明性的例子。 Thus, here it comes: 因此,它来了:

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")
)

As you can see, the DataFrame is piped through the functions, and filter_columns is one of them. 如您所见,DataFrame通过函数传递,而filter_columns是其中之一。 However, the function is pre-configured and returns a function that only takes a DataFrame, similar to a decorator. 但是,该函数是预先配置的,并且返回一个仅接受DataFrame的函数,类似于装饰器。 The same behaviour could be achieved with this: 可以通过以下方式实现相同的行为:

def filter_columns(*args):
    def f(df):
        return df[[*args]]
    return f

However, I would always have to run two calls then, eg filter_columns()(df) , and that is what I would like to avoid. 但是,我总是必须接着运行两次调用,例如filter_columns()(df) ,这是我要避免的事情。

well I am unfamiliar with toolz module, but it looks like there is no easy way of curry a function with arbitrary number of arguments, so lets try something else. 好吧,我不熟悉toolz模块,但是似乎没有简单的方法来咖喱具有任意数量参数的函数,因此让我们尝试其他方法。

First as a alternative to 首先作为替代

def filter_columns(*args):
    def f(df):
        return df[*args]
    return f

(and by the way, df[*args] is a syntax error ) (顺便说一下, df[*args]是语法错误)

to avoid filter_columns()(data) you can just grab the last element in args and use the slice notation to grab everything else, for example 为了避免filter_columns()(data)您可以只获取args的最后一个元素,并使用切片符号来获取其他所有内容,例如

def filter_columns(*argv):
    df, columns = argv[-1], argv[:-1]
    return df[columns]

And use as filter_columns(df) , filter_columns("date", "temperature", df) , etc. 并用作filter_columns(df)filter_columns("date", "temperature", df)等。

And then use functools.partial to construct your new, well partially applied, filter to build your pipe like for example 然后使用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")
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM