组合函数和功能模块

发布于 2024-12-28 13:22:02 字数 1457 浏览 1 评论 0原文

Python 3.2 文档 指 < a href="http://oakwinter.com/code/function/" rel="nofollow noreferrer">Collin Winter 的 function 模块,其中包含函数 compose

compose()函数实现函数组合。在其他方面 换句话说,它返回一个围绕外部和内部可调用对象的包装器,例如 内部的返回值直接输入到外部。

不幸的是,这个模块自 2006 年 7 月以来就没有更新过;我想知道有没有可以替代的。

目前,我只需要 compose 函数。以下原始 function.compose 定义对于 Python 3 仍然适用吗?

def compose(func_1, func_2, unpack=False):
    """
    compose(func_1, func_2, unpack=False) -> function

    The function returned by compose is a composition of func_1 and func_2.
    That is, compose(func_1, func_2)(5) == func_1(func_2(5))
    """
    if not callable(func_1):
        raise TypeError("First argument to compose must be callable")
    if not callable(func_2):
        raise TypeError("Second argument to compose must be callable")

    if unpack:
        def composition(*args, **kwargs):
            return func_1(*func_2(*args, **kwargs))
    else:
        def composition(*args, **kwargs):
            return func_1(func_2(*args, **kwargs))
    return composition

SO问题有些相关;它询问 Python 是否应该支持 compose 的特殊语法。

Python 3.2 documentation refers to Collin Winter's functional module which contains function compose:

The compose() function implements function composition. In other
words, it returns a wrapper around the outer and inner callables, such
that the return value from inner is fed directly to outer.

Unfortunately, this module hasn't been updated since July 2006; I wonder if there's any replacement available.

For now, I only need compose function. Is the following original functional.compose definition still good for Python 3?

def compose(func_1, func_2, unpack=False):
    """
    compose(func_1, func_2, unpack=False) -> function

    The function returned by compose is a composition of func_1 and func_2.
    That is, compose(func_1, func_2)(5) == func_1(func_2(5))
    """
    if not callable(func_1):
        raise TypeError("First argument to compose must be callable")
    if not callable(func_2):
        raise TypeError("Second argument to compose must be callable")

    if unpack:
        def composition(*args, **kwargs):
            return func_1(*func_2(*args, **kwargs))
    else:
        def composition(*args, **kwargs):
            return func_1(func_2(*args, **kwargs))
    return composition

This SO question is somewhat related; it asks whether Python should support special syntax for compose.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧故 2025-01-04 13:22:02

正如上面评论中所讨论的,您的 compose 实现对于 python 3.2 有效。
您提供的库的大多数函数都在 文档 中编写了等效的 python 函数。

mapfilter 等函数已经在 Python 中实现,也可以简单地表示为列表推导式。 Python 有一个 id 函数返回对象的标识(作为整数),但是库的 id 函数可以表示为 lambda x: x.

您可能会感兴趣的另一个模块是 itertoolsfunctools,它们具有 partialreduce (类似于 >foldl 但参数顺序不同)。

以下是我在标准库中找不到的其中一些的简单实现:

from functools import reduce

def flip(f):
    if not callable(f):
        raise TypeError("Cannot filp a non-callable object")
    def result(*args, **kw):
        args = list(args)
        args.reverse()
        return f(*args, **kw)
    return result

def ilast(i):
    return reduce(lambda _, x: x, i)

def iscanl(f, v, seq):
    yield v
    for a in seq:
        v = f(v, a)
        yield v

def scanl(*args, **kw):
    return list(iscanl(*args, **kw))

def foldl(*args, **kw):
    return ilast(iscanl(*args, **kw))
# Or using reduce
#def foldl(f, v, seq):
#    return reduce(f, seq, v)

def iscanr_reverse(f, v, seq):
    return iscanl(flip(f), v, seq)

def scanr(*args, **kw):
    result = list(iscanr_reverse(*args, **kw))
    result.reverse()
    return result

def foldr(*args, **kw):
    return ilast(iscanr_reverse(*args, **kw))

Your implementation of compose is valid for python 3.2 as discussed in the comments above.
Most of the functions of the library you gave have a python equivalent written in the documentation.

Functions such as map and filter are already implemented in python and can also be simply expressed as list comprehensions. Python has an id function returning the identity of an object (as integer), but the id function of the library can be expressed as lambda x: x.

Another modules you might find interesting are itertools and functools which has partial and reduce (which is similar to foldl but the argument order is not the same).

Here is a simple implementations of a few of them that I didn't find in the standard library:

from functools import reduce

def flip(f):
    if not callable(f):
        raise TypeError("Cannot filp a non-callable object")
    def result(*args, **kw):
        args = list(args)
        args.reverse()
        return f(*args, **kw)
    return result

def ilast(i):
    return reduce(lambda _, x: x, i)

def iscanl(f, v, seq):
    yield v
    for a in seq:
        v = f(v, a)
        yield v

def scanl(*args, **kw):
    return list(iscanl(*args, **kw))

def foldl(*args, **kw):
    return ilast(iscanl(*args, **kw))
# Or using reduce
#def foldl(f, v, seq):
#    return reduce(f, seq, v)

def iscanr_reverse(f, v, seq):
    return iscanl(flip(f), v, seq)

def scanr(*args, **kw):
    result = list(iscanr_reverse(*args, **kw))
    result.reverse()
    return result

def foldr(*args, **kw):
    return ilast(iscanr_reverse(*args, **kw))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文