2016-01-31 62 views
11

Sto usando Python, e ho una funzione che prende una lista come argomento. Per esempio, io sto usando la seguente sintassi,Come passare una lista come input di una funzione in Python

def square(x,result= []): 
    for y in x: 
     result.append=math.pow(y,2.0) 
     return result 

print(square([1,2,3])) 

e l'uscita è [1] solo quando dovrei ottenere [1,4,9].

Cosa sto sbagliando?

+13

1. Non creare argomenti di default mutabili. 2. Puoi solo restituire una volta. – jonrsharpe

+1

Quindi, come posso restituire un array come output. Puoi darmi qualche idea? Grazie –

+3

Porta il ritorno fuori dal ciclo for. –

risposta

14

Stai ritornando un valore da una funzione nella prima iterazione del ciclo for. Per questo motivo, la seconda e la terza iterazione del ciclo for non hanno mai luogo. È necessario spostare la vostra dichiarazione return al di fuori del ciclo come segue:

import math 

def square(x): 
    result = [] 
    for y in x: 
     result.append(math.pow(y,2.0)) 
    return result 

print(square([1,2,3])) 

uscita

[1.0, 4.0, 9.0] 
+0

Come qualcuno ha usato per rafforzare la programmazione basata piuttosto che basata su indentazione, devo dire che una singola scheda che cambia da dove la funzione ritorna è qualcosa che trovo orribilmente non intuitiva. – Pharap

+0

Ma indentri ancora il tuo codice anche se usi le parentesi graffe, vero? – Matthias

18

Perché non superare il problema completamente?

def square(vals): 
    return [v*v for v in vals] 

Edit: Il primo problema, come molte persone hanno fatto notare, è che si sono in corto circuito il ciclo for. Il tuo return dovrebbe essere dopo il il ciclo, non in esso.

Il prossimo problema è l'utilizzo di list.append - è necessario chiamarlo, non assegnarlo ad esso, ovvero result.append(y*y). result.append = y*y sovrascrive invece il metodo con un valore numerico, probabilmente generando un errore la prossima volta che provi a chiamarlo.

volta a risolvere che, troverete un altro errore meno evidente si verifica se si chiama la funzione più volte:

print(square([1,2,3])  # => [1, 4, 9] 
print(square([1,2,3])  # => [1, 4, 9, 1, 4, 9] 

Perché si passa un oggetto mutabile (una lista) come impostazione predefinita, ogni ulteriore uso di tale l'elemento predefinito punta a lo stesso elenco originale.

Invece, tenta

def square(vals, result=None): 
    if result is None: 
     result = [] 
    result.extend(v*v for v in vals) 
    return result 
+2

Questo in realtà non dice all'OP dove stanno andando male ed è solo un rivestimento di come quadrare un array – ShaneQful

+1

@ShaneQful: per favore dare un altro sguardo. –

+0

Mi scuso, il mio commento iniziale sopra era basato sulla tua risposta succinta iniziale. Avere un voto in su :) – ShaneQful

3

Si dovrebbe tornare al di fuori del ciclo for. Altrimenti, si fermerà dopo la prima iterazione.

def square(x): 
    result=[] 
    for y in x: 
     result.append=math.pow(y,2.0) 
    return result 

print(square([1,2,3]) 
+0

Append è una funzione che non si desidera sovrascrivere qui. –

6

Usiamo anche result? Puoi usare una comprensione di lista per generare il tuo risultato che poi ritorni. Non sono sicuro del motivo per cui hai passato result come variabile nella funzione, poiché non è utilizzato.

Inoltre, avere return result all'interno del ciclo significa che la funzione restituisce il valore alla prima iterazione, quindi restituisce semplicemente il quadrato del primo numero nell'elenco.

import math 

def square(x): 
    return [math.pow(y, 2) for y in x] 

>>> print(square([1,2,3])) 
[1.0, 4.0, 9.0] 
+0

Beh, potrebbe essere visto come il valore iniziale, per esempio. Forse OP intendeva 'square ([1,2,3], [100,200,300])' per restituire '[100,200,300,1,4,9]'. – muru

0

il tuo codice non ha senso da nessuna parte. errore di sintassi alla fine manca la parentesi di chiusura per la stampa, richiama la chiamata all'interno del ciclo for che significa che viene eseguita una volta sola e il risultato.append è una funzione non un costruttore sp la chiamata corretta è

result.append(math.pow(y,2)) 

l'unica cosa che non è un problema è il passaggio della lista che è la tua domanda, la funzione sta ricevendo l'intera lista se lo fai

def f(a): 
    print a 
f([1,2,3]) 

fuori

[1,2,3,] 
3

potreste essere interessati a utilizzare yield

def square(x): 
    for y in x: 
     yield math.pow(y, 2.0) 

in questo modo è possibile chiamare

for sq in square(x): 
    ... 

che non genererà l'intero elenco delle piazze in una sola volta, ma piuttosto un elemento per iterazione, o utilizzare list(square(x)) per ottenere l'elenco completo su richiesta.

2

Questa è una divertente opportunità di utilizzare uno stile leggermente più funzionale:

import math 
map(lambda x:(math.pow(x,2)), [1,2,3]) 

Questa utilizza la funzione map, che prende una lista e una funzione, e restituisce una nuova lista in cui tale funzione è stata applicata singolarmente a ciascun membro della lista. In questo caso, applica la funzione math.pow(x,2) a ciascun membro dell'elenco, dove ogni numero è x.

Si noti che map(lambda x:(math.pow(x,2)), [1,2,3]) restituisce un iterabile, che è davvero conveniente, ma se è necessario recuperare una lista, è sufficiente racchiudere l'intera istruzione in list().

Problemi correlati