List 模拟长度函数得到一个列表';s长度
我试图模拟Mathematica v.8中的长度函数来得到列表的长度。鉴于这一事实:List 模拟长度函数得到一个列表';s长度,list,function,wolfram-mathematica,List,Function,Wolfram Mathematica,我试图模拟Mathematica v.8中的长度函数来得到列表的长度。鉴于这一事实: 空列表表示为{} l=Rest[l]将不带第一个元素的列表l分配给l(这是一个列表) 半路 这是我使用mathematica的第一年,我在这方面不太在行,所以我所做的事情可能有些(或所有)问题: Ej1[l_List] := Module[{i, v}, v = {{}}; i = 1; While[l != v, l = Rest[l]; i++] Return[i] ] l={a,b,c,d,e} 当
- 空列表表示为{}
- l=Rest[l]将不带第一个元素的列表l分配给l(这是一个列表)
- 半路
Ej1[l_List] := Module[{i, v},
v = {{}};
i = 1;
While[l != v, l = Rest[l]; i++]
Return[i]
]
l={a,b,c,d,e}
当我尝试运行它时,循环永远不会结束,它会给我以下警告:
Set::shape: Lists {a,b,c,d,e} and {b,c,d,e} are not the same shape. >>
Set::shape: Lists {a,b,c,d,e} and {b,c,d,e} are not the same shape. >>
Set::shape: Lists {a,b,c,d,e} and {b,c,d,e} are not the same shape. >>
General::stop: Further output of Set::shape will be suppressed during this calculation. >>
主要问题是您试图修改输入变量
l
,这是不可能的,并且您缺少分号
Ej1[l_List] := Module[{i = 0, v = {}, thisl},
thisl = l;
While[thisl != v, thisl = Rest[thisl]; i++];
i]
递归地使用
If[]
:
ClearAll[f];
f[l_List, i_: 0] := If[l != {}, f[Rest[l], i + 1], i];
f[{1,2}]
(*
-> 2
*)
与belisarius相同,但未明确写入
If
:
ClearAll[ej2];
ej2[lst_ /; (lst == {}), i_: 0] := i
ej2[lst_, i_: 0] := ej2[Rest[lst], i + 1]
ej2[{1, 2, 3, 4, 5}]
(*
5
*)
您还可以使用
nestwile
:
Clear[f];
f[l_List] := NestWhile[{Rest[#[[1]]], (#[[2]]) + 1} &, {l, 0},
(#[[1]] != {}) &][[2]]
此代码不受$RecursionLimit
或$IterationLimit
的限制,因此它也适用于非常大的列表。缺点是它不是很有效,因为在每个迭代步骤中,都会有剩余列表的副本。对列表中的元素进行计数的一种更快的方法是
f2[l_List] := Fold[(# + 1) &, 0, l]
作为比较:
list=RandomReal[1,10000];
Timing[f[list]]
(* ==> {3.35747, 10000} *)
Timing[f2[list]]
(* ==> {0.000658, 10000} *)
这里是另一个递归解决方案,我认为这是一个相当惯用的函数式编程:
myLength[{}] := 0
myLength[lis_List] := 1 + myLength[Rest[lis]]
In[47]:= myLength[{}]
Out[47]= 0
In[48]:= myLength[{1}]
Out[48]= 1
In[49]:= myLength[{1,2,3,4,5}]
Out[49]= 5
我只是注意到你在三分钟前发布了相同的答案。如果您更正您的,使它与{}一起工作,我将删除mine@Szabolcs说得好,我删除了
:0
来调试其他东西,但忘了把它放回去。。。虽然+1,但无需删除您的。由于Fold
能够自动编译折叠函数,因此加速效果非常显著。哈,谢谢!我仍然很忙,老实说,现在很难找到一个没有答案的问题,但这是一件好事+1--我仍然认为Sjoerd的代码在大多数背景下都比较容易,但这很好。
myLength[{}] := 0
myLength[lis_List] := 1 + myLength[Rest[lis]]
In[47]:= myLength[{}]
Out[47]= 0
In[48]:= myLength[{1}]
Out[48]= 1
In[49]:= myLength[{1,2,3,4,5}]
Out[49]= 5