2012-10-25 10 views
6

Dies ist eine grundlegende Frage zur Listenmanipulation in Mathematica. Ich habe eine große Liste, in der jedes Element die folgende schematische Form hat: {List1, List2, Number}. Zum BeispielSchnelle Extraktion von Elementen aus verschachtelten Listen

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

Ich möchte eine neue Liste erstellen, die nur einige Teile aus jeder Unterliste enthält. ZB, wählen Sie das dritte Element aus jeder Unterliste, um {5,10,15} von oben zu erhalten. Oder lassen Sie das dritte Element fallen, um {{{1,2,3}, {1,3,2}}, {{1,4,5}, {1,0,2}}, {{4,5, 3}, {8,3,4}}}.

Ich kann dies tun, indem Sie die Tabelle Befehl neue Listen zu erstellen, zum Beispiel

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

aber ich frage mich, ob es eine schneller war muss Art und Weise, die auf große Listen funktionieren würde.

Antwort

7

In Mathematica Version 5 und höher, können Sie das Schlüsselwort Alle auf vielfältige Weise verwenden können, um eine Liste Traversal angeben

Zum Beispiel, anstelle Ihrer Tabelle können Sie schreiben

Hier konvertiert Mathematica All in alle akzeptablen Indizes für die ersten Dimen Dann nimmt die dritte die nächste Dimension.

In der Regel ist es effizienter, eine Schleife mit der Mathematica-Programmiersprache zu erstellen. Es ist wirklich gut für homogene Listen, wo die Dinge, die Sie auswählen oder scannen immer existieren.

Eine andere effiziente Notation und Abkürzung ist die ;; Syntax:

a[[ All, 1 ;; 2]] 

wird die erste Stufe eines Scans und alles vom 1. bis zum 2st Elemente jeden sublist nehmen, genau wie Ihr zweiten Fall.

In der Tat alle und ;; kann zu beliebig vielen Ebenen kombiniert werden. ;; kann auch in einer Weise zu jeder Iterator in Mathematica ähnlich verwendet werden:

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

als

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

die gleichen Dinge tun, und Sie können einen von Start-, End- oder Schritt auslassen, wird gefüllt mit Der Standardwert von 1, Länge [(der impliziten Liste)] und 1.

Eine andere Sache, die Sie in Mathematica Hilfe suchen könnten, sind ReplacePart und MapAt, die programmatischen Ersatz von strukturierten Ausdrücken ermöglichen. Der Schlüssel zur effizienten Verwendung ist, dass Sie in ReplacePart patterns verwenden können, um die Koordinaten der zu ersetzenden Objekte anzugeben, und Sie können Funktionen definieren, die auf sie angewendet werden.

Beispiel mit Ihren Daten

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

wird jeden dritten Teil jeder Unterliste mit 0.

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

ersetzen wird jeden dritten Teil jeden sublist verdoppeln.

+0

Danke; das ist, was ich gesucht habe. – bartimaeus

+1

Beachten Sie, dass Sie für weitere Fragen auch unter http://mathematica.stackexchange.com fragen können – ogerard

1

können Sie verwenden Part (Stenografie [[...]]) hierfür:.

a[[All, 3]] 

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

Wie die Autoren schlagen vor, die Ansätze auf Basis von Teil müssen wohlgeformte Daten, sondern Fälle ist für robuste Trennung von Listen gebaut:

Arbeiten mit ein,

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} 

Die anderen Stücke ein Datensatz kann durch ähnliche Formulare extrahiert werden.

Teil basierte Ansätze werden knebeln auf schlecht gebildete Daten wie:

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]] 

, aber Fälle werden Müll überspringen, nur auf konforme Daten

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

{5, 10, 15} 

hth Betrieb

Fred Klingner

Verwandte Themen