在Mathematica中重新排序列表元素的更好方法

时间:2011-12-26 05:16:02

标签: wolfram-mathematica

我想根据Tally[Characters["2723198931"]]的每个元素的第一个组件重新排序lst = {"3", "1", "2", "9"}的结果。也就是说,我希望输出为{{{"3", 2}}, {{"1", 2}}, {{"2", 2}}, {{"9", 2}}}

目前我有一种丑陋的解决方案,但想知道是否有人可以帮助提供简洁的解决方案。非常感谢。

3 个答案:

答案 0 :(得分:5)

一种方式可能是

data = Tally[Characters["2723198931"]];
lst = {"3", "1", "2", "9"};

(*algorithm*)

pos =  Position[data[[All, 1]], #] & /@ lst;
Extract[data, pos]

输出

{{{"3", 2}}, {{"1", 2}}, {{"2", 2}}, {{"9", 2}}}

更新凌晨2:37

上面的屏幕截图,我在Windows 7上使用v 8.04

enter image description here

答案 1 :(得分:4)

这应该很快,但我没有测试它。在长列表中,您可以使用Dispatch[rls]获得更好的效果。

key = {"3", "1", "2", "9"};
tal = Tally[Characters["2723198931"]];

rls = #[[1]] -> # & /@ tal;
key /. rls
{{"3", 2}, {"1", 2}, {"2", 2}, {"9", 2}}

或者你可以使用它,这对于长Tally列表来说要快一点:

rls = Thread[tal[[All, 1]] -> tal];

答案 2 :(得分:2)

或者,您可以执行类似

的操作
With[{tal = Tally[Characters["2723198931"]]},
  Flatten@Pick[tal, tal[[All, 1]], #] & /@ key] 

您是否一直在计算字符串中的字符数?如果是这样,直接计算字符可能更有效,而不是首先将其转换为字符列表。考虑例如

str = StringJoin[RandomChoice[CharacterRange["0", "9"], 1000]];
key = {"3", "1", "2", "9"};

({#, StringCount[str, #]} & /@ key) // Timing

(* output: {0.000121, {{"3", 98}, {"1", 112}, {"2", 99}, {"9", 107}}} *)

With[{tal = Tally[Characters[str]]},
  Flatten@Pick[tal, tal[[All, 1]], #] & /@ key] // Timing 

(* output: {0.000567, {{"3", 98}, {"1", 112}, {"2", 99}, {"9", 107}}} *)