从嵌套列表中快速提取元素

时间:2012-10-25 05:44:24

标签: wolfram-mathematica

这是关于Mathematica中列表操作的基本问题。 我有一个大型列表,其中每个元素都有以下原理图形式:{List1,List2,Number}。例如,

a = {{{1,2,3},{1,3,2},5},{{1,4,5},{1,0,2},10},{{4,5,3},{8,3,4},15}}}

我想制作一个新列表,其中只包含每个子列表中的一些部分。例如,从每个子列表中挑出第三个元素,从上面给出{5,10,15}。或者删除第三个元素以返回{{{1,2,3},{1,3,2}},{{1,4,5},{1,0,2}},{{4,5, 3},{8,3,4}}}

我可以使用table命令构建新列表,例如

Table[a[[i]][[3]],{i,1,Length[a]}

但我想知道是否有一种必须更快的方法可以在大型列表上运行。

3 个答案:

答案 0 :(得分:7)

在Mathematica第5版及更高版本中,您可以使用关键字All以多种方式指定列表遍历。

例如,您可以编写

代替您的表格
a[[All,3]]

在这里,Mathematica将All转换为第一维的所有可接受的索引,然后取下一维的第3维。

这样做通常比使用Mathematica编程语言进行循环更有效。对于同源列表来说,这是非常好的,你想要选择或扫描的东西总是存在。

另一种有效的符号和捷径是;;语法:

a[[ All, 1 ;; 2]]

将扫描a的第一级并从每个子列表的第1个元素到第2个元素中取出所有内容,与第二个案例完全相同。

实际上All and ;;可以组合到任意数量的级别。 ;;甚至可以以类似于Mathematica中的任何迭代器的方式使用:

a[[ start;;end;;step ]]

会做与

相同的事情
Table[ a[[i]], {i,start,end,step}]

并且你可以省略start,end或step中的一个,它的默认值为1,Length [(隐式列表)]和1。

您可能希望在Mathematica的帮助中查找的另一件事是ReplacePartMapAt,它们允许以编程方式替换结构化表达式。有效使用它的关键是在ReplacePart中,您可以使用patterns来指定要替换的事物的坐标,并且您可以定义要应用于它们的函数。

您的数据示例

ReplacePart[a, {_, 3} -> 0]

将用0替换每个子列表的每个第3部分。

ReplacePart[a, {i : _, 3} :> 2*a[[i, 3]]]

将每个子列表的每个第3部分加倍。

答案 1 :(得分:2)

正如作者所说,基于Part的方法需要格式良好的数据,但是案例是为了强有力地分离列表而构建的:

使用你的

a = {{{1, 2, 3}, {1, 3, 2}, 5}, {{1, 4, 5}, {1, 0, 2}, 
10}, {{4, 5, 3}, {8, 3, 4}, 15}};

Cases[a,{_List,_List,n_}:>n,Infinity]

{5, 10, 15}

记录的其他部分可以通过类似的形式提取。

基于部分的方法会对不良形式的数据嗤之以鼻:

badA = {{{1, 2, 3}, {1, 3, 2}, 5}, {{1, 4, 5}, {1, 0, 2}, 
10}, {{4, 5, 3}, {8, 3, 4}, 15}, {baddata}, {{1, 2, 3}, 4}};

badA[[All,3]]

{{{1, 2, 3}, {1, 3, 2}, 5}, {{1, 4, 5}, {1, 0, 2},
10}, {{4, 5, 3}, {8, 3, 4}, 15}, {baddata}, {{1, 2, 3},
4}}[[All, 3]]

,但是案例将跳过垃圾,仅在符合要求的数据上运行

Cases[badA, {_List, _List, s_} :> s, Infinity]

{5, 10, 15}

HTH,

弗雷德克林格纳

答案 2 :(得分:1)

您可以使用Part(简写[[...]])

a[[All, 3]]

a[[All, {1, 2}]]