So entfernen Sie das zusätzliche {} beim Zuordnen einer Funktion zu einer Liste

7

Einfache Frage, angesichts einer solchen Liste

%Vor%

und nehme an, dass ich eine Funktion wie folgt definiert habe:

%Vor%

Und ich möchte diese Funktion auf die Liste anwenden, also wenn ich

tippe %Vor%

Dies ergibt

%Vor%

Ich möchte, dass es als

herauskommt %Vor%

so funktioniert es.

Was ist der beste Weg, dies zu tun? Angenommen, ich kann die Funktion foo [] Definition nicht ändern (sagen wir, es ist eingebaut)

Nur zwei Möglichkeiten, die ich jetzt kenne, sind

%Vor%

(zu viel Arbeit) oder

%Vor%

(weniger tippen, aber zuerst transponieren)

Frage: Gibt es noch andere bessere Möglichkeiten, um das oben genannte zu tun? Ich schaute auf andere Map und seine Freunde, und ich konnte keine Funktion sehen, um es direkter zu machen, als was ich habe.

    
Nasser 06.01.2012, 22:54
quelle

5 Antworten

14

Sie benötigen Apply at Level 1 oder ihre Kurzform @@@

%Vor%     
abcd 06.01.2012, 22:56
quelle
7

Eine Möglichkeit besteht darin, den Kopf jedes Elements von lst von List zu foo :

zu ändern %Vor%     
Andrei 06.01.2012 23:06
quelle
6

Nur um rätselhafte Leistungstests der beiden Methoden zu melden ( @@@ , @@ # & /@ ):

%Vor%

Diese Ergebnisse sind nicht zufällig, sondern in etwa proportional für sehr unterschiedliche Datengrößen.

@@@ ist ungefähr 3-4 mal schneller für Subtract , Divide , Power , Log und @@ # & /@ ist 4 mal schneller für Plus und Times , was zu weiteren Fragen führt , die (wie man glauben kann) leicht sein könnte verdeutlicht durch folgende Bewertung:

%Vor%

Nur Plus und Times haben die Attribute Flat und Orderless , während unter anderem nur Power (was dort relativ effizient erscheint) auch das Attribut OneIdentity hat.

Bearbeiten

Eine zuverlässige Erklärung der beobachteten Leistungssteigerungen (dank Leonid Shifrins Ausführungen) sollte einen anderen Weg gehen.

Standardmäßig gibt es MapCompileLength -> 100 , da wir die Auswertung von SystemOptions["CompileOptions"] prüfen können. Um die Autokompilierung von Map zurückzusetzen, können wir Folgendes auswerten:

%Vor%

Nun können wir die relative Leistung der beiden Methoden testen, indem wir noch einmal unsere H - Leistungstestfunktion für verwandte Symbole und Liste auswerten:

%Vor%

Mit diesen Ergebnissen können wir schlussfolgern, dass Yodas Ansatz ( @@@ ) am effizientesten ist, während der von Andrei im Fall von Plus und Times aufgrund der automatischen Kompilierung von Map erlaubt ist bessere Leistung von ( @@ # & /@ ).

    
Artes 07.01.2012 01:29
quelle
4

Ein paar weitere Möglichkeiten zur Auswahl:

Dieser ist eine ausführlichere Version von yodas Antwort. Sie wendet foo nur auf Stufe 1 der Liste lst an (ersetzt die Überschrift List mit der Überschrift foo ):

%Vor%

Das macht dasselbe, aber bildet Apply über der Liste lst ab (im Wesentlichen Andreis Antwort):

%Vor%

Und das ersetzt einfach das Muster List [x__] mit foo [x] auf Level 1:

%Vor%     
Arnoud Buzing 07.01.2012 01:25
quelle
3

Die Antworten auf Apply[] sind genau richtig und das Richtige, aber was Sie versuchen wollten, war ein List[] head durch ein Sequence[] head zu ersetzen, dh List[List[3,5],List[6,7]] sollte es werden List[Sequence[3,5],Sequence[6,7]] .

Der Sequenzkopf bleibt natürlich, wenn ein Kopf einer Liste von Parametern gelöscht wird, also würden Delete[Plus[3,5],0] und Delete[{3,5},0] und Delete[List[3,5],0] alle Sequence[3,5] erzeugen.

So wird foo@Delete[#,0]&/@{{a, b}, {c, d}, {e, f}} Ihnen dasselbe geben wie foo@@@{{a, b}, {c, d}, {e, f}} .

Alternativ macht foo[#/.List->Sequence]&/@{{a, b}, {c, d}, {e, f}} dasselbe.

    
Gregory Klopper 07.01.2012 01:45
quelle

Tags und Links