如何在基于元素的列表上进行类似Tally的操作' Mathematica中的总数

时间:2011-12-19 05:18:30

标签: wolfram-mathematica

例如,我有一个列表:

{{1, 2, 3}, {6}, {4, 5}, {1, 6}, {2, 2, 3, 2}, {9}, {7}, {2, 5}}

我希望根据列表元素的总数得到一个统计列表。

在这种情况下,我希望输出为:

{{6, {{1, 2, 3}, {6}}, {7, {{2, 5}, {1, 6}, {7}}}, {9, {{4, 5}, {2, 2, 3, 2}, {9}}}}}

如何在Mathematica中方便地做到这一点?

非常感谢。

3 个答案:

答案 0 :(得分:5)

这是我的尝试 - 比Yoda的

更简单一点
lst = {{1, 2, 3}, {6}, {4, 5}, {1, 6}, {2, 2, 3, 2}, {9}, {7}, {2, 5}};

{Total@First@#, #} & /@ GatherBy[lst, Total]

如果您不想重复元素,则可以使用

{Total@First@#, Union[#]} & /@ GatherBy[lst, Total]

或者,如果你真的想要一个类似计数的操作

{Total@First@#, Tally[#]} & /@ GatherBy[lst, Total]

答案 1 :(得分:4)

虽然我可能会像@Simon那样做,但我们不要忘记ReapSow也可以使用:

Reap[Sow[#, Total[#]] & /@ lst, _, List][[2]]

其中lst是原始列表。这比基于GatherBy的代码效率稍低,但速度也相当快。通过将其重写为

,可以将上述代码加速大约1.5倍
Reap[Sow @@@ Transpose[{lst, Total[lst, {2}]}], _, List][[2]]

在这种情况下,它比基于GatherBy的代码慢大约1.5倍。请注意,这两种方法之间的速度差异并不是非常显着,因为列表是不规则的,因此没有打包,GatherBy这里没有压缩数组通常享有的速度优势。

答案 2 :(得分:2)

不要忽视Tr。这更短更快:

{Tr@#, {##}} & @@@ GatherBy[lst, Tr]