gpt4 book ai didi

相当于 Mathematica 的 Sow/Reap 的 Python

转载 作者:太空狗 更新时间:2023-10-29 18:30:42 32 4
gpt4 key购买 nike

假设我在 Mathematica 中定义了以下函数:

f[list_] := Map[Prime[Sow[#]] &, list];

它输出一个素数列表,这样如果输入列表在位置 i 有 n 个,那么输出列表将在位置 i 包含第 n 个素数。例如,

In[2]:= f[{1, 3, 4}]

Out[2]= {2, 5, 7}

现在,如果出于某种原因(调试等...),我想检查将哪些值输入到 Prime 函数中。由于函数中的 Sow 命令,我可以这样做

In[3] := Reap[f[{1, 3, 4}]]

Out[3] := {{2, 5, 7}, {{1, 3, 4}}}

有关 Sow/Reap 的更多详细信息,请参阅 Wolfram Documentation .我的问题是,是否存在与 Mathematica 的 Sow 和 Reap 功能等同的自然 Python 功能?特别是,是否有一种方法可以在不从您想要执行的 python 函数中显式返回额外内容的情况下执行此类操作它是,编写第二个几乎相同但返回额外内容的 python 函数,还是使用全局变量?

最佳答案

我想出了两种方法来实现类似这样的基本版本,每种方法都有其自身的局限性。这是第一个版本:

farm = []

def sower(func):
def wrapped(*args, **kw):
farm.append([])
return func(*args, **kw)
return wrapped

def sow(val):
farm[-1].append(val)
return val

def reap(val):
return val, farm.pop()

您可以像这样使用它(基于 Mathematica 文档页面中的示例之一):

>>> @sower
... def someSum():
... return sum(sow(x**2 + 1) if (x**2 + 1) % 2 == 0 else x**2 + 1 for x in xrange(1, 11))
>>> someSum()
395
>>> reap(someSum())
(395, [2, 10, 26, 50, 82])

这有一些限制:

  1. 任何想要使用sow 的函数都必须使用sower 装饰器进行装饰。这意味着您不能像 Mathematica 示例那样在内联表达式中使用 sow ,例如列表理解。您也许可以通过检查调用堆栈来解决这个问题,但它可能会变得丑陋。
  2. 任何播种但未收获的值(value)都会永远存储在“农场”中,因此农场会随着时间的推移变得越来越大。
  3. 它没有文档中显示的“标签”功能,尽管添加起来并不难。

写这篇文章让我想到了一个更简单的实现,但权衡略有不同:

farm = []

def sow(val):
if farm:
farm[-1].append(val)
return val

def reap(expr):
farm.append([])
val = expr()
return val, farm.pop()

这个你可以像这样使用,它有点类似于 Mathematica 版本:

>>> reap(lambda: sum(sow(x**2 + 1) if (x**2 + 1) % 2 == 0 else x**2 + 1 for x in xrange(1, 11)))
(395, [2, 10, 26, 50, 82])

这个不需要装饰器,它会清理获得的值,但它需要一个无参数函数作为它的参数,这需要你将你的播种表达式包装在一个函数中(这里使用 lambda )。此外,这意味着 reaped 表达式调用的任何函数中的所有播种值都将插入到同一个列表中,这可能会导致奇怪的排序;我无法从 Mathematica 文档中判断那是 Mathematica 所做的还是什么。

关于相当于 Mathematica 的 Sow/Reap 的 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18818755/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com