我想根据Tally[Characters["2723198931"]]
的每个元素的第一个组件重新排序lst = {"3", "1", "2", "9"}
的结果。也就是说,我希望输出为{{{"3", 2}}, {{"1", 2}}, {{"2", 2}}, {{"9", 2}}}
。
目前我有一种丑陋的解决方案,但想知道是否有人可以帮助提供简洁的解决方案。非常感谢。
答案 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
答案 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}}} *)