我在Wolfram Mathematica 8.0中有一个嵌套列表,如:
{{1,1,1},{0,0},{1,1,1,1,1},{0},{1,1},{0}}
并希望用子串长度替换那些,如下所示:
{{3,3,3},{0,0},{5,5,5,5,5},{0},{2,2},{0}}
有人能告诉我这个问题的快速功能方法吗?
答案 0 :(得分:7)
list = {{1, 1, 1}, {0, 0}, {1, 1, 1, 1, 1}, {0}, {1, 1}, {0}};
Map[Length[#]*# &, list]
Out[193]= {{3, 3, 3}, {0, 0}, {5, 5, 5, 5, 5}, {0}, {2, 2}, {0}}
答案 1 :(得分:4)
如果
list = {{1, 1, 1}, {0, 0}, {1, 1, 1, 1, 1}, {0}, {1, 1}, {0}};
然后
list /. {items : 1 ..} :> ConstantArray[Length[{items}], Length[{items}]]
(将所有由一个或多个1组成的列表替换为相应长度的列表,其长度为值)给出:
{{3, 3, 3}, {0, 0}, {5, 5, 5, 5, 5}, {0}, {2, 2}, {0}}
答案 2 :(得分:2)
让
f := # /. (x_List /; Union@x=={1}) :> Table[Length@x, {Length@x}] &
用作
f/@list
更好(并且窃取Jan的答案的一部分):
f2 := # /. ConstantArray[1, Length@#] :> ConstantArray[Length@#, Length@#] &
答案 3 :(得分:1)
目前尚不清楚您的数据可能包含哪些变体。如果你的子列表都是单调零或一个,那么丹尼尔的方法是有效的。如果您需要更快的速度,可以使用:
f = Compile[{{s, _Integer, 1}}, If[s[[1]] == 1, s*Length@s, s]];
f /@ list
如果子列表可能包含其他元素和/或混合,则需要进行更多测试。我会给您留下最适合您数据的测试:
list /. x : {1 ..} :> (ConstantArray[#, #] &@Length@x)
list /. {x : 1 ..} :> ConstantArray[+x, +x]
list /. x : {1 ..} :> x * Tr@x
最后对任何“代码高尔夫”球迷来说:
list /. {x:1..}:>+x{x}