7

这是 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]}

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

4

3 回答 3

7

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

例如,代替你的表,你可以写

a[[All,3]]

在这里,Mathematica 将 All 转换为第一个维度的所有可接受的索引,然后采用下一个维度的第三个索引。

这样做通常比使用 Mathematica 编程语言循环更有效。对于您想要挑选或扫描的东西总是存在的同质列表来说,这真的很好。

另一个有效的符号和快捷方式是 ;; 句法:

a[[ All, 1 ;; 2]]

将扫描 a 的第一级并获取每个子列表的第一个到第二个元素的所有内容,就像你的第二种情况一样。

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

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

会做同样的事情

Table[ a[[i]], {i,start,end,step}]

并且您可以省略 start、end 或 step 之一,它使用默认值 1、Length[(隐式列表)] 和 1 填充。

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

您的数据示例

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

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

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

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

于 2012-10-25T06:29:33.740 回答
3

正如作者所建议的,基于 Part 的方法需要格式良好的数据,但 Cases 是为强大的 List 分离而构建的:

使用你的,

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会跳过垃圾,只对符合的数据进行操作

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

{5, 10, 15}

h,

弗雷德·克林格

于 2012-10-26T14:36:40.760 回答
1

你可以使用Part(这个的简写[[...]])

a[[All, 3]]

a[[All, {1, 2}]]
于 2012-10-25T06:26:26.803 回答