2016-03-19 9 views
6

Voglio solo utilizzare il ciclo for per la variabile t nella mia funzione:Come posso usare un ciclo 'for' per una sola variabile in una funzione che dipende da due variabili?

l = [] 

def func(s): 
    for i in range(1, 100): 
     t = i 
     p = t * 2 + s * 2 
    return p 

l.append(func(10)) 

print l 

Voglio che il valore di t per andare da 1 a 99 e e stampare un elenco di tutto il valore, ma ho sempre finiscono per ottenere l = [218].

+2

@AlbertoBonsanto: il problema con l'indentazione di fissaggio dovrebbe essere ora evidente. Il 'return' era davvero parte del ciclo' for' nella funzione? E perché non hai indentato il corpo della funzione? –

+0

@MartijnPieters Mi dispiace che stavo modificando nel momento esatto! Non ho fatto finta di sovrascrivere il tuo! –

+0

Considera questo? 'func = lambda s: [(t * 2) + s * 2 per t in range (1, 100)]' – Signal

risposta

41

Suppongo tu abbia installato NumPy (almeno la tua domanda originale lo ha suggerito), quindi ti presenterò un modo come puoi ottenere il risultato utilizzando numpy-arrays in un modo molto efficiente (senza alcuna lista-comprensioni e le iterazioni espliciti):

> import numpy as np 
> s = 10 
> l = np.arange(1, 100) * 2 + s * 2 # Arrange produces an array. Syntax is like "range". 
> print(l) 

array([ 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 
     48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 
     74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 
     100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 
     126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 
     152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 
     178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 
     204, 206, 208, 210, 212, 214, 216, 218]) 

ho usato il fatto che le operazioni matematiche su array NumPy influiscono su tutti gli elementi. Perciò è tanto facile scrivere l'operazione: np.arange(1, 100) * 2, perché moltiplica ogni elemento con 2 e numpy.arange è la possibilità di creare una matrice contenente tutti i numeri tra un determinato start e stop con opzionale step (proprio come il python range).

Con NumPy non sarebbe una buona scelta per i valori singoli append (perché questo ricrea l'intero array e non solo i valori appends). Nella maggior parte dei casi è meglio creare un array con le dimensioni e la forma finali e operare direttamente su di esso. Naturalmente puoi ordinare concatenate o append diversi array NumPy, ma come detto crea sempre un array completamente nuovo e quindi non è molto efficiente (se usato regolarmente).


Così ora un paio di osservazioni sul tentativo iniziale e perché non ha funzionato: La vostra funzione create un sacco di numeri, ma li sovrascrive in ogni ciclo e restituisce solo l'ultimo:

def func(s): 
    for i in range(1, 100): 
     t = i 
     p = t * 2 + s * 2 
     # Next iteration of the loop just overwrites p 
    # Returns only the last p 
    return p 

si potrebbe fare di questo un generatore (con yield invece di return), ma questo è probabilmente eccessivo qui, ti faccio vedere che comunque :-)

l = [] 
def func(s): 
    for i in range(1, 100): 
     p = i * 2 + s * 2 
     yield p 

l.append(list(func(10))) # Need to convert the generator to a list here. 
# In this case a simple "l = list(func(10))" would be easier if you don't need to append. 
+0

quando si utilizza il generatore 'yield', i risultati vengono visualizzati come 1 elemento in un elenco. come posso stampare 'def func (s)' in modo che io possa tracciarlo su un'altra lista –

+0

@ p.kumar come si usa il generatore? Almeno in quel modo con 'list (func (s))' sembra funzionare bene sul mio computer, il risultato è una lista contenente 99 elementi. Riguardo al 'plotting', date un'occhiata a [' matplotlib.pyplot.plot'] (http://matplotlib.org/api/pyplot_api.html). – MSeifert

4

Si sta calcolando un valore più volte (senza aggiungerlo a un elenco), quindi aggiungendo il valore finale a un elenco.

Invece, vogliamo aggiungere alla lista mentre procediamo.

def func(s): 
    l = [] 
    for i in range(1, 100): 
     l.append(i*2+s*2) 
    return l 

Si può anche fare questo in una sola riga con un list comprehension se si sta andando per brevità.

func = lambda s: [(t*2)+s*2 for t in range(1, 100)] 

uscita:

[22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218] 

Annotare il 218 alla fine. Come ho detto prima, stavi solo restituendo l'ultimo valore, quindi il tuo programma ha emesso 218.

+4

Anche se insisti su un solo rivestimento inutile, è meglio farlo con 'def', non' lambda'; 'lambda' significa che la funzione non conosce il proprio nome, che rompe cose semplici come il pickling (implicitamente implicato in cose come' multiprocessing' o 'concurrent.futures' o anche' copy.deepcopy' in alcuni casi). 'def func (s): return [(t * 2) + s * 2 per t in range (1, 100)]' è uguale a un solo lato, in modo simile conciso e più funzionale (nel senso inglese, non il senso del linguaggio design). – ShadowRanger

0

Poiché ci ar e un sacco di soluzione che. Con diverse librerie o generatori. Hai avuto solo problemi di indentazione nel tuo codice ed era pronto a volare. Ecco la piccola modifica nel tuo codice.

#In Python3 
def func(s): 
    for i in range(1,100): 
     p = i * 2 + s * 2 
     l.append(p) 
    return l 
l =[] 
print(func(10)) 
Problemi correlati