f [arg1, arg2, …, argN] vs. f [{arg1, arg2, …, argN}] (Italiano)

Sto cercando di riprodurre lAPI di una funzione (scritta in R) che accetta un numero arbitrario di argomenti e lo gestisce allo stesso modo in cui gestirebbe un singolo argomento che è un elenco di diversi set di dati.

Esiste un linguaggio di Mathematica che consente di definire una funzione in modo che:

f[ arg1, arg2, ..., argN ] 

si comporti lo stesso di

f[ {arg1, arg2, ..., argN} ] 

?

Commenti

  • Potresti semplicemente scrivere f[args___]:= f[{args}] e quindi fornire la definizione di f[{arg1_, arg2_,...}].

Risposta

Come descritto da Andy Ross in un commento, puoi creare una definizione che preelabora gli argomenti in una forma canonica. Riportando il suo esempio semplicemente per illustrare la flessibilità:

f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3] 

True

Questo metodo è utile per una preelaborazione più complicata, ma in casi semplici come questo è spesso più facile usare Alternatives:

g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3] 

True

Ricorda che quando utilizzando Alternatives devi manualmente ordinare i pattern, poiché vengono provati in sequenza. Il pattern args__ | {args__} non funzionerebbe come desiderato perché args__ corrisponderà a {12, 7, 3} come singolo argomento .

Risposta

Ci sono molti modi per gestire questa situazione. Lapproccio che molto probabilmente adotterò può essere illustrato dal seguente esempio:

f[seqn : ___] := Module[{args = {seqn}}, Switch[args, {{___}}, "List of args", {_}, "One arg", {_, __}, "Two or more args", {}, "No args" ]] f[{x, y, z}] (* ==> "List of args" *) f[{x}] (* ==> "List of args" *) f[] (* ==> "No args" *) f[x] (* ==> "One arg" *) f[x, y, z] (* ==> "Two or more args" *) 

Ovviamente, ogni applicazione di questa tecnica sostituirebbe le stringhe viste qui con alcune azione appropriata alle proprie esigenze.

Un altro approccio consiste nello scrivere funzioni separate per ogni modello di argomento che si desidera gestire:

g[args : {___}] := "List of args" g[] := "No args" g[arg_] := "One arg" g[arg_, rest__] := "Two or more args" g[{x, y, z}] (* ==> "List of args" *) g[{x}] (* ==> "List of args" *) g[] (* ==> "No args" *) g[x] (* ==> "One arg" *) g[x, y, z] (* ==> "Two or more args" *) 

Commenti

  • Qual è il tuo ragionamento per " molto probabilmente " utilizzando Switch su più definizioni? Switch di solito è più lento e non dovrebbe essere utilizzato senza motivo, IMHO.
  • @ Mr.Wizard. Lutilizzo di Switch fa appello al mio senso dellestetica della programmazione perché organizza tutte le alternative in modo che possano essere gestite in ununica funzione. ' di solito non sono così preoccupato per la velocità di esecuzione, non finché lesecuzione lenta non diventa davvero evidente.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *