使用可选的具体化使函数可列出

2024-06-01 20:47:46 发布

您现在位置:Python中文网/ 问答频道 /正文

问题简介

嗨,我最近从Mathematica转到了Python编程语言,因为我想让我的代码更易于移植和更强大。我研究了Functional Programming HOWTO guide,开始研究高阶函数。在

对于Python语言的函数范式的新手来说,让我感到困惑的是高阶函数的默认行为,即标准执行。{heck>请参见下面的一个示例{heck>应用下面的一个对象映射:

odd = lambda x : x%2!=0
lis = [1, 6, 2, 5, 9, 4]
map(odd, lis)

Out[171]: <map at 0x19e6a228e48>

Mathematica的用户希望在一个列表上“线程”odd(),而计算的结果将是布尔值的列表。在python中,必须使用list()构造函数具体化结果,例如:

^{pr2}$

我错过了什么

我在Python中缺少的一个特性是可供线程使用的函数的可列表属性。实际上这是一个core feature in Wolfram Mathematica language。但是Python中最漂亮的地方是所有的东西都是一个对象(Wolfram语言中的表达式),包括函数,因此我可以通过传递关键字参数来改变函数对象的行为方式,以指示我希望函数返回生成器/迭代器还是完整的具体化结果。在

完整答案的规格

因此,这就是Python语言的高级核心开发人员要问的问题。继续上面的例子,odd()是一个接受一个参数的函数,如果PyFunctionObject有一个materialize和{}属性,我希望它能写

odd.listable = True
odd.materialize = True
odd(1, 6, 2, 5, 9, 4)

Out[172]: [True, False, False, True, True, False]

odd(6)

Out[173]: False

或者切换到map()时的默认行为。。。在

odd.listable = True
odd.materialize = False
odd(1, 6, 2, 5, 9, 4)

Out[31]: <generator object Listable.__call__.<locals>.<genexpr> at 0x000001F3BBF1CC50>

参考文献

我在stackoverflow中搜索过类似的问题,最近找到的是这个问题:Automatically use list comprehension/map() recursion if a function is given a list。大卫罗宾逊的答案是基于装饰师。早在1999年,michaelvanier也发布了这个答案here,这是这个问题的基于类的解决方案。在

我的问题稍有不同,因为我要问的是如何在较低的级别上调整函数对象,以便获得我所描述的理想行为。我在这里还认为,这个特性将使Python函数编程对新手来说更容易,也更有趣,首先,他们不需要学习生成器和迭代器。如果Python的路线图中已经有这样的讨论,请让我知道。在


Tags: 对象函数答案语言falsetruemap列表
2条回答

这个答案不能完全覆盖我的问题,因为我在问如何修改核心函数类型的行为(它是PyFunctionObject吗?)。尽管如此,我还是想和其他用户分享,因为通过这段代码我学到了很多东西,这是我能找到的最接近的答案。它是根据1999年的一个旧的post of Michael Vanier设计的。 接下来是:

class Listable(object):
    """
    Listable functions, are functions which automatically map themselves over a sequence.  
    This idea is borrowed from Mathematica.
    """

    def __init__(self, f, materialize=True):
        self.func  = f
        self.gen = not materialize

    def __call__(self, *args):
        # check the number of arguments
        if len(args)==1:
            # return a scalar
            return self.func(*args)
        elif self.gen:
            # return a generator 
            return (self.func(x) for x in args)
        else:
            # return an iterator
            return [self.func(x) for x in args]

已经有一种完美的Python式的方式来“物化”懒惰的构造。用list()包装它。list构造函数接受任何序列并将其转换为列表。在

>>> odd(1, 6, 2, 5, 9, 4)
<generator object odd at ...>

list(odd(1, 6, 2, 5, 9, 4))
[True, False, False, True, True, False]

在一个函数上设置“开关”来改变它的行为意味着函数不再可能是“纯粹的”,它既不是Python式的,也不是函数式的。在

相关问题 更多 >