Mathematica地图问题

时间:2010-11-08 18:39:10

标签: map wolfram-mathematica

原始问题:

我知道Mathematica有一个内置的地图(f,x),但这个功能是什么样的?我知道你需要查看列表中的每个元素。

任何帮助或建议?

编辑(由Jefromi,Mike的评论拼凑而成):

我正在开发一个程序,需要通过像Map这样的列表,但我不允许使用它。我也不允许使用Table;我需要在没有其他功能帮助的情况下浏览列表。我正在处理一个递归版本,我有一个空列表,但是在列表中包含其中的项目并没有成功。这是我的第一个案例:newMap[#, {}] = {}(空列表的地图只是一个空列表)

2 个答案:

答案 0 :(得分:6)

我发布了一个递归解决方案但后来决定将其删除,因为从评论中这听起来像是一个家庭作业问题,而且我通常是一个教导鱼人。

您正在使用定义newMap[f_, {}] := {}的递归解决方案。

Mathematica的模式匹配是你的朋友。考虑如何实现newMap[f_, {e_}]的定义,并从那里newMap[f_, {e_, rest___}]

最后一个提示:一旦你可以定义最后一个函数,你实际上并不需要{e_}的情况。

<强>更新

根据您的评论,这个例子可能会帮助您了解如何应用任意函数:

func[a_, b_] := a[b]

In[4]:= func[Abs, x]
Out[4]= Abs[x]

<强>解

由于OP捕获了一条鱼,可以这么说(恭喜!)这里有两个递归解决方案,以满足任何旁观者的好奇心。第一个可能是我认为的“惯用语”Mathematica:

map1[f_, {}] := {}
map1[f_, {e_, rest___}] := {f[e], Sequence@@map1[f,{rest}]}

这种方法不能充分利用模式匹配,这基本上是OP最终的结果:

map2[f_, {}] := {}
map2[f_, lis_] :=  {f[First[lis]], Sequence@@map2[f, Rest[lis]]}

{f[e], Sequence@@map[f,{rest}]}部分可以用各种等效方式表达,例如:

  • Prepend[map[f, {rest}], f[e]]
  • Join[{f[e]}, map[f, {rest}](@Mike使用此方法)
  • Flatten[{{f[e]}, map[f, {rest}]}, 1]

我会让读者继续思考,并思考大多数人的表现影响=)

最后,为了好玩,这是一个程序版本,即使写它让我有点恶心:; - )

map3[f_, lis_] :=
 (* copy lis since it is read-only *)
 Module[{ret = lis, i},
  For[i = 1, i <= Length[lis], i++,
   ret[[i]] = f[lis[[i]]]
   ];
  ret
  ]

答案 1 :(得分:1)

要回答你在评论中提出的问题,Map中的第一个参数是一个接受单个参数的函数。这可以是纯函数,也可以是只接受单个参数的函数的名称,如

In[1]:=f[x_]:= x + 2
       Map[f, {1,2,3}]
Out[1]:={3,4,5}

关于如何用你自己设计的递归函数替换Map ......在Jefromi的例子之后,我不会放弃太多,因为这是作业。但是,您显然需要某种方式对列表的某个部分进行操作,同时保持列表的其余部分对于映射函数的递归部分保持不变。正如他所说,Part是一个很好的起点,但我会查看它引用的其他一些函数,看看它们是否更有用,例如FirstRest。另外,我可以看到Flatten在哪里有用。最后,您需要一种方法来结束递归,因此学习如何约束模式可能很有用。顺便提一下,这可以用一行或两行完成,具体取决于你是否为地图创建了第二个定义(更简单的方法)。

提示:既然您已经有了最终条件,那么您需要回答三个问题:

  1. 如何从列表中提取单个元素
  2. 如何引用列表的其余元素,
  3. 我该如何重新组合?
  4. 有助于考虑流程中的一个步骤,以及在该步骤中您需要完成的任务。