1

在 Mathematica 中,我试图在更复杂的表达式中使用转换,同时将表达式映射到列表上。由于某种原因,使用转换规则会产生完全不同的值,但我无法从文档中说出原因。

Clear[x, values]

values = {{1}, {2, Null, 3}, {4, 5, Null, 6, Null }}
Out[122]= {{1}, {2, Null, 3}, {4, 5, Null, 6, Null}}

Length[x] /. x -> DeleteCases[#, Null] & /@ values
Out[123]= {0, 0, 0}

Length[DeleteCases[#, Null]] & /@ values
Out[124]= {1, 2, 3}

更新:到目前为止,Length[x]即使x未定义,我也能够确定这是一个有效的表达式,因为 to 的参数Length[]是一个表达式,它返回该表达式中的组件数。现在我需要了解如何将评估延迟到x替换之后。

4

3 回答 3

1

要在评估左侧之前进行替换,您可以使用Unevaluated

Unevaluated[Length[x]] /. x -> DeleteCases[#, Null] & /@ values
{1, 2, 3}

阅读Robby Villegas 的Working with Unevaluated Expressions以详细了解这个头。


专用 StackExchange 站点:
在此处输入图像描述

于 2013-08-05T21:40:45.243 回答
1

您可以定义自己的长度函数,该函数仅评估列表(或其他)

length[v_List] := Length[v]
length[x] /. x -> DeleteCases[#, Null] & /@ values

(* 1 2 3 *)

或者更笼统地说..

length[v_ /; Head[v] =!= Symbol] := Length[v]
于 2013-08-01T19:43:59.570 回答
1

我能够防止使用Hold[]and对表达式进行早期评估ReleaseHold[]

In[229]:= ReleaseHold[Hold[Length[x]] /. x -> {1, 2, 3}]
Out[229]= 3

Length[x] /. x -> {1, 2, 3}
Out[230]= 0

在原始问题上下文中,这是我能够解决的方法:

ReleaseHold[Hold[Length[x]] /. x -> DeleteCases[#, Null]] & /@ values
于 2013-08-01T20:03:44.980 回答