我一直在学习更多地使用Map(成为更多功能的程序员)。看起来Map想要一个列表作为应用函数的表达式。如果表达式不是列表,则表示不满意。
我在这个例子中使用NumberForm来说明我的意思:
我可以在整个列表中映射NumberForm确定:
data = {1, 2, 3}
Map[NumberForm[#, {3, 2}] &, data]
但是,如果我尝试将其映射到列表中的某个特定元素,请说上面的第一个,它不起作用
data = {1, 2, 3}
Map[NumberForm[#, {3, 2}] &, data[[1]] ]
返回的结果未格式化。与原始数据相同。即我回到'1'而不是'1.00',就像在其他例子中一样。
要解决这个问题,我添加了额外的{}
data = {1, 2, 3}
Map[NumberForm[#, {3, 2}] &, {data[[1]]} ]
现在可以使用,(只需要使用{}
从结果中删除First
)。
所以我想,为什么不一直添加这个额外的{}
并最终删除它?
这样,我不必担心我的Maping功能是不是像上面那样的列表?
所以,我的例子都会变成这样:
data = {1, 2, 3}
First@Map[NumberForm[#, {3, 2}] &, { data } ]
First@Map[NumberForm[#, {3, 2}] &, { data[[1]] } ]
通过这种方式,代码将适用于所有内容,如果我正在应用Map的地址与列表不同,我无需在使用Map之前进行特殊检查。
问题是:上述内容对专家来说是否是一个好的解决方案,还是有更好的方法来解决这个问题?
答案 0 :(得分:3)
也许我在这里不理解你的意图,但是如果你在列表中的某个特定条目上查找Map
函数,那么MapAt
就是你正在寻找的函数。例如:
MapAt[NumberForm[#, {3, 2}] &, data, 1]
Out[1]= {1.00,2,3}
此处,该函数仅应用于列表中的第一个元素。
答案 1 :(得分:2)
这恰好可行,因为NumberForm
适用于列表:
NumberForm[{1, 2, 3}, {3, 2}]
给出
{1.00, 2.00, 3.00}
Map[f, {{a, b, c}}]
只需将f
映射到First[{{a,b,c}}]
,即映射到{a,b,c}
;所以你得到f[{a,b,c}]
。
所以不幸的是,添加{}
通常无效。
一种简单的方法是定义
ClearAll[map]
map[f_, head_[els__]] := Map[f, head[els]]
map[f_, el_] := f[el]
何处
map[f, {a, b, c}]
map[f, a]
给
{f[a], f[b], f[c]}
f[a]
然而,这不允许使用Map[f,expr,levelspec]
形式(但这很容易实现)。
这也适用于这种情况:
map[f, g[a, b, c]] == Map[f, g[a, b, c]]
(*
True
*)
答案 2 :(得分:2)
我看到了几个不同的问题
Map
有哪些不同的方法?毫不奇怪,因为列表是Mathematica操作的基础,所以有很多方法可以对它们进行转换。但是,由于f
和{l1, l2, ...}
给了我{f@l1, l2, ...}
,所以我没有任何直接的方法告诉Mathematica。如果您要将f
应用于l
的第一个元素(例如,在将f应用于所有l之前进行测试),您也可以执行f/@l[[1;;1]]
。 (编辑@yoda提到MapAt
有这种行为,可以指定一组应该映射的位置。)Listable
属性。然后,如果我们定义:f[a_AtomicType]
,f[a:{_AtomicType..}]
会给出f/@a
编辑 - 实际上,给定f[a_AtomicType]:=something
,f[a_List]
给出f/@a
的结果,即使a的某些元素没有头AtomicType
- 即可列表函数不要验证列表中的所有元素都有f
方面的转换规则。如果您关心这一点,则需要单独定义f[a:{_AtomicType..}]:=f/@a
,而不是让您的函数Listable
。
另外,@ Nasser,看起来你的第一个例子中的行为是因为Map[f,a_AtomicType]
返回a
。另请注意,Map
可以使用任何头部映射表达式,而不仅仅是List
。
答案 3 :(得分:2)
这似乎是一个奇怪的问题。为什么在写First@Map[f, { x } ]
时写f @ x
?
Map
的第二个参数可能是哪种形式?
也许你会从最后的级别找到映射值:
Map[f, {x, y, z}, {-1}]
Map[f, x, {-1}]
小心这一点,就好像列表元素不是原子元素一样,你会得到意想不到的结果。
或者,你可以写:
data = {1, 2, 3};
data /. n_?NumberQ :> NumberForm[n, {3, 2}]
data[[1]] /. n_?NumberQ :> NumberForm[n, {3, 2}]