簡體   English   中英

Python 嵌套柯里化

[英]Python nested currying

我試圖在 這里解決一個 codewars 問題,但我有點卡住了。 我相信我應該在 Python 中使用嵌套柯里化。

讓我們以添加為例。 讓我們進一步限制問題,讓嵌套加法在右側工作,即寫一個加法 function 這樣


print((add)(3)(add)(5)(4))

打印 12。

應該可以根據需要將它嵌套得盡可能深,例如我想要

print((add)(add)(3)(4)(add)(5)(6))

應該給我18。

到目前為止我所做的 -

我最初的嘗試是使用以下嵌套的 function -

def add_helper():
    current_sum = 0

    def inner(inp):
        if isinstance(inp, int):
            nonlocal current_sum
            current_sum += inp
            print(f"current_sum = {current_sum}")

        return inner

    return inner


add = add_helper()

但是,這並不能解決問題。 相反,我得到以下 output,因為當我執行類似print((add)(add)(3)(4)(add)(5)(6))的操作時

current_sum = 3
current_sum = 7
current_sum = 12
current_sum = 18
<function add_helper.<locals>.inner at 0x...>

有誰知道我必須如何更改我的 function 以便我只返回 18,因為 function 會知道它已“完成”?

任何幫助將不勝感激!

更新

在查看了Bharel 的評論之后,到目前為止我有以下內容 -


def add_helper():
    val = 0
    ops_so_far = []
    def inner(inp):
        if isinstance(inp, int):
            nonlocal val
            val += inp
            return inner
        else:
            ops_so_far.append(("+", val))
            inp.set_ops_so_far(ops_so_far)
            return inp
    def set_ops_so_far(inp_list):
        nonlocal ops_so_far
        ops_so_far = inp_list

    def get_val():
        nonlocal val
        return val

    def get_ops_so_far():
        nonlocal ops_so_far
        return ops_so_far

    inner.get_ops_so_far = get_ops_so_far
    inner.set_ops_so_far = set_ops_so_far
    inner.get_val = get_val
    return inner


def mul_helper():
    val = 1
    ops_so_far = []
    def inner(inp):

        if isinstance(inp, int):
            nonlocal val
            val *= inp
            return inner
        else:
            ops_so_far.append(("*", val))
            inp.set_ops_so_far(ops_so_far)
            return inp

    def get_ops_so_far():
        nonlocal ops_so_far
        return ops_so_far

    def set_ops_so_far(inp_list):
        nonlocal ops_so_far
        ops_so_far = inp_list

    def get_val():
        nonlocal val
        return val

    inner.get_ops_so_far = get_ops_so_far
    inner.get_val = get_val
    inner.set_ops_so_far = set_ops_so_far

    return inner


add = add_helper()
mul = mul_helper()

現在當我這樣做


res = (add)(add)(3)(4)(mul)(5)(6)
print(res.get_ops_so_far())
print(res.get_val())

我明白了

[('+', 0), ('+', 7)]
30

仍然不確定這是否是正確的方向?

這就是我為仍在尋找未來的任何人解決它的方式 -


from copy import deepcopy


def start(arg):
    def start_evalutaion(_arg, eval_stack, variables):
        new_eval_stack = deepcopy(eval_stack)
        new_variables = deepcopy(variables)
        to_ret = evaluate_stack(_arg, new_eval_stack, new_variables)

        if to_ret is not None:
            return to_ret

        def inner(inner_arg):

            return start_evalutaion(
                inner_arg, new_eval_stack, new_variables
            )

        return inner
    return start_evalutaion(arg, [], dict())


add = lambda a, b, variables: variables.get(a, a) + variables.get(b, b)
sub = lambda a, b, variables: variables.get(a, a) - variables.get(b, b)
mul = lambda a, b, variables: variables.get(a, a) * variables.get(b, b)
div = lambda a, b, variables: variables.get(a, a) // variables.get(b, b)


def let(name, val, variables):
    variables[name] = val
    return


def return_(val, variables):
    return variables.get(val, val)

def evaluate_stack(_arg, eval_stack, variables):
    if callable(_arg):
        if _arg.__name__ == "return_":
            req_args = 1
        else:
            req_args = 2
        eval_stack.append((_arg, req_args, []))
    else:
        while True:
            func_to_eval, req_args, args_so_far = eval_stack[-1]
            args_so_far.append(_arg)
            if len(args_so_far) == req_args:
                eval_stack.pop()
                _arg = func_to_eval(*args_so_far, variables)
                if func_to_eval.__name__ == "return_":
                    return _arg
                elif _arg is None:
                    break
            else:
                break


通過所有測試用例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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