2013-08-01 96 views
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有效的表達,因爲參數Length[]是返回該表達元件數量的表達式。現在我需要了解如何延遲評估,直到x被替換之後。

+0

感謝接受。我希望能在[Mathematica.SE]上看到你,我注意到你註冊了。 –

回答

1

爲了使更換前的左手側進行評估,您可以使用Unevaluated

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

閱讀由Robby Villegas爲Working with Unevaluated Expressions的詳細瞭解這個頭。


專用StackExchange網站:
enter image description here

1

可以定義一個只會評估列表自己的長度函數(或其他)

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

(* 1 2 3 *)

或許更一般..

length[v_ /; Head[v] =!= Symbol] := Length[v] 
+0

這似乎在某些情況下工作,雖然在我的Mathematica抱怨,因爲我用它作爲函數的參數,並且頭與這個表達式和另一個參數之間不匹配。 –

1

我能夠使用Hold[]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