2012-05-29 19 views
9

En Python, puede pasar una lista o tupla a una función y hacer que la función descomprima el argumento. ¿Cómo puedo hacer eso en Clojure? Aquí es un código de ejemplo Python:Cómo desestructurar un vector para utilizarlo como argumento de función

def f (a, b, c, *d): 
    print "a: ", a 
    print "b: ", b 
    print "c: ", c 
    print "d: ", d 

f (1, 2, 3, 4, 5, 6) 

print 
v = (4, 5, 6) 
f(1, 2, 3, *v) 

resultado:

a: 1 
b: 2 
c: 3 
d: (4, 5, 6) 

a: 1 
b: 2 
c: 3 
d: (4, 5, 6) 

en mi código clojure:

(defn f [a b c & d] 
    (println "a: " a) 
    (println "b: " b) 
    (println "c: " c) 
    (println "d: " d)) 

(f 1 2 3 4 5 6) 

(println) 
(def v [4 5 6]) 
(f 1 2 3 v) 

resultado:

a: 1 
b: 2 
c: 3 
d: (4 5 6) 

a: 1 
b: 2 
c: 3 
d: ([4 5 6]) 

la D tienen un único elemento ¿Cómo puedo dejar que el resultado sea un código python?

Respuesta

11

Clojure no descomprime argumentos de un vector con una función de idioma, como hace Python.

Lo más parecido a desempacar es la función apply.

En este caso en particular:

(def v [4 5 6]) 
(apply f (concat [1 2 3] v)) 

Lienzo:

a: 1 
b: 2 
c: 3 
d: (4 5 6) 
+1

O simplemente (se aplican f 1 2 3 v) – Alex

+0

(aplicar f (concat [1 2 3] v)) es genial, puedo concat otros: (aplicar f (concat [1 2 3] v [7 8 9])) –

0

Para cualquier argumento en Clojure, se puede determinar si el argumento es un valor escalar o una secuencia mediante el uso secuencial? En el pseudo-código de abajo,

(if (sequential? v) 
    (do-something-because-it's-a-sequence v) 
    (do-something-different-because-it's-not-a-sequence v)) 

Así, en Clojure, que puede lograr la misma tarea que en su ejemplo Python determinando si usted tiene una secuencia o no.

+0

para determinar el elemento d, ¿usar secuencial? es mejor, (seq? [1 2 3]) => falso –

3

Solo para completar.

Digamos que tiene una función que toma un vector [d1 d2 d3] como argumento

(defn f 
    [a b c [d1 d2 d3]] 
    (println "a: " a) 
    (println "b: " b) 
    (println "c: " c) 
    (println "d1: " d1) 
    (println "d2: " d2) 
    (println "d3: " d3)) 

De esta manera podemos tener los 3 primeros elementos del vector que se pasa a la función f como d1 d2 d3. Llamando a los resultados de la función anteriores en la siguiente salida:

=> (f 1 2 3 [6 7 8 9]) 
a: 1 
b: 2 
c: 3 
d1: 6 
d2: 7 
d3: 8 

Tenga en cuenta que a pesar de que el vector contiene 4 artículos, sólo tomar la primera 3.

Cuestiones relacionadas