2009-07-17 7 views
18

Come viene chiamato questo linguaggio?Denominare questo costrutto del linguaggio python/ruby ​​(utilizzando i valori dell'array per soddisfare i parametri della funzione)

In Python posso dire:

def a(b,c): return b+c 
a(*[4,5]) 

e ricevere 9. Analogamente in rubino:

def a(b,c) b+c end 
a(*[4,5]) 

Come si chiama, quando si passa un singolo array ad una funzione che richieda diversamente multipla argomenti?

Qual è il nome dell'operatore *?

Quali altre lingue supportano questa interessante funzionalità?

+0

Duplicato http://stackoverflow.com/questions/918449/questo-è-il-operatore-do-per-questo-in-rubia/918475 – seth

+2

@seth: No, non un duplicato. La domanda a cui ti sei collegato riguarda la * semantica * di questo operatore (in Ruby); questa domanda riguarda * la terminologia *. – ThomasH

risposta

26

I documenti Python lo chiamano Unpacking Argument Lists. È una caratteristica piuttosto utile. In Python, puoi anche usare un doppio asterisco (**) per decomprimere un dizionario (hash) in argomenti di parole chiave. Funzionano anche al contrario. Posso definire una funzione come questa:

def sum(*args): 
    result = 0 
    for a in args: 
     result += a 
    return result 

sum(1,2) 
sum(9,5,7,8) 
sum(1.7,2.3,8.9,3.4) 

Per raggruppare tutti gli argomenti in una lista di dimensioni arbitrarie.

+2

Ho saputo di questo per un po ', e ciecamente usato una volta e un po', ma mai veramente capito. Bella spiegazione chiara e semplice. – monkut

+0

+1 "Argument Unpacking" è il termine generale che ho sempre sentito. – Chuck

+0

il trucco di reimballaggio funziona allo stesso modo nel rubino – rampion

2

L'ho chiamato "lista di espansione", ma non penso che sia la terminologia standard (non credo che ce ne sia ...). Il Lisp in tutte le versioni (Scheme included) e Haskell e altri linguaggi funzionali, possono farlo abbastanza facilmente, ma non credo sia facile da fare nelle lingue "mainstream" (forse puoi farcela come una "riflessione". in qualche!-).

+0

Non conosco nessuna terminologia standard, ma ho sempre pronunciato "* args" come "star args" e "** kwargs" 'kay word args'. Sono sicuro che altri hanno la loro terminologia, e sono curioso di sentirlo. –

10

In rubino, è spesso chiamato "splat".

Anche in ruby, è possibile utilizzarlo per indicare "tutti gli altri elementi nell'elenco".

a, *rest = [1,2,3,4,5,6] 
a  # => 1 
rest # => [2, 3, 4, 5, 6] 

Può apparire anche su entrambi i lati dell'operatore di assegnazione:

a = d, *e 

In questo utilizzo, è un po 'come CDR regime, anche se non deve essere tutto ma la testa del elenco.

+1

L'operatore splat è il termine utilizzato in The Ruby Programming Language, che è presumibilmente co-scritto da Matz (creazione di Ruby) – Svend

+4

La sintassi "tutti gli altri elementi nella lista" (con un nome stellato sul lato sinistro di il compito) è stato aggiunto in Python 3: il tuo esempio funzionerà senza modifiche. Inoltre (in Python 3), la variabile a stelle non deve essere l'ultima: 'a, b, * middle, y, z = range (10)' funziona. Tuttavia, non può apparire sul lato destro di un compito, ma non è realmente necessario, dal momento che puoi fare 'l = list (a, * b)'. – Miles

+0

Sì, penso di ricordare di averlo letto. Io uso ancora python 2.4-2.6 al lavoro (e continuerò a farlo, sospetto). Ho appena fatto un test con Ruby 1.8 e * var dev'essere l'ultimo della lista. –

5

La terminologia tipica è denominata "applicazione di una funzione a un elenco", o "apply" in breve.

Vedi http://en.wikipedia.org/wiki/Apply

E 'stato in LISP fin quasi dalla sua nascita nel 1960 dispari. pitone Glad riscoprì: -}

Apply è in genere su un lista o una rappresentazione di una lista come come un array. Tuttavia, è possibile applicare funzioni agli argomenti che provengono da altre parti, come le strutture. La nostra lingua PARLANSE ha tipi fissi (int, float, stringa, ...) e strutture. Stranamente, un elenco di argomenti funzione assomiglia molto a una definizione di struttura , e in PARLANSE, è è una definizione di struttura, ed è possibile "applicare" una funzione PARLANSE a una struttura compatibile. Si può "fare" istanze di struttura, anche, in tal modo:

 

(define S 
    (structure [t integer] 
       [f float] 
       [b (array boolean 1 3)] 
    )structure 
)define s 

    (= A (array boolean 1 3 ~f ~F ~f)) 

    (= s (make S -3 19.2 (make (array boolean 1 3) ~f ~t ~f)) 


    (define foo (function string S) ...) 

    (foo +17 3e-2 A) ; standard function call 

    (foo s) ; here's the "apply" 

PARLANSE sembra Lisp, ma non lo è.

+1

Chiamare una sintassi varargs "applicare una funzione a un elenco" è semplicemente sbagliato, IMO. Anche il riferimento a PARLANSE non sembra dare un contributo. – ThomasH

+1

@Thomas: OP ha detto chiaramente "passa una matrice a una funzione per più argomenti". A piacere o no, sta applicando una funzione a una rappresentazione di una lista. OP ha anche chiesto altre lingue "con questa interessante funzionalità"; l'esempio di PARLANSE è simile ma diverso e viene fornito come contrasto. –

+0

Direi (come ThomasH) che c'è una differenza significativa tra apply, che esegue la stessa funzione n volte sugli elementi di una lista, e splat/var-args che chiama la funzione una volta con gli elementi della lista come parametri. –

3

Rubino chiama splat, anche se David Black ha anche venire con l'ordinata UNAR {, ra} operatore y (cioè unario operatore unarray)

1

La maggior parte delle domande sono già state risposta, ma alla domanda "Qual è il nome dell'operatore *?": il termine tecnico è "asterisco" (deriva dalla parola latina asterisco, che significa "piccola stella", che, a sua volta, proviene dal Greco 01στερίσκος). Spesso, tuttavia, verrà indicato come "stella" o, come detto sopra, "splat".

+1

+1 per la risata, anche se non era previsto. – nilamo

2

Haskell ha troppo (per coppie), con la funzione uncurry:

ghci> let f x y = 2*x + y 
f :: (Num a) => a -> a -> a 
ghci> f 1 2 
4 
ghci> f 10 3 
23 
ghci> uncurry f (1,2) 
4 
ghci> uncurry f (10,3) 
23 

E 'possibile fare in un operatore, quindi è più splat-simile:

ghci> f `uncurry` (1,2) 
4 
ghci> let (***) = uncurry 
(***) :: (a -> b -> c) -> (a, b) -> c 
ghci> f *** (10,3) 
23 

E anche se sarebbe facile definire funzioni simili per i casi 3-tupla, 4-tuple, etc, non c'è alcuna funzione generale per n -tuple (come splat funziona in altre lingue) a causa della rigorosa digitazione di Haskell.