2014-12-10 13 views
6

Sto cercando di imparare pulito modi divinatorio di fare le cose, e si chiedeva il motivo per cui il mio ciclo for non può essere riscritta in questo modo:linea per il ciclo

q = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5] 
vm = [-1, -1, -1, -1] 

for v in vm: 
    if v in q: 
     p.append(q.index(v)) 
    else: 
     p.append(99999) 

vm[p.index(max(p))] = i 

Ho provato a sostituire il ciclo for con:

[p.append(q.index(v)) if v in q else p.append(99999) for v in vm] 

Ma non funziona. Il ciclo for v in vm: elabora i numeri da vm in base a quando vengono successivamente in q.

+0

si consiglia di utilizzare - 1 invece di 99999 per un flag di un valore inesistente (quindi funzionerebbe anche per un elenco con 99999+ elementi) –

+0

l'elenco completo funzionerà ma restituirà gli elenchi di Nessuno anche – Hackaholic

+0

Ho usato 99999 invece di -1 perché più tardi ho eseguito devono essere selezionati valori max (p) e inesistenti. – Will

risposta

10

Quello che si utilizza è un list comprehension in Python, non un ciclo in linea (anche se è simile a uno). Si potrebbe scrivere il ciclo come una lista di comprensione in questo modo:

p = [q.index(v) if v in q else 99999 for v in vm] 

Quando si utilizza una lista di comprensione, non si chiama list.append perché l'elenco è in costruzione dalla comprensione stessa. Ogni elemento nell'elenco sarà restituito dall'espressione a sinistra della parola chiave for, che in questo caso è q.index(v) if v in q else 99999. Per inciso, se si utilizza list.append all'interno di una comprensione, si otterrà un elenco di valori None poiché questo è ciò che il metodo append restituisce sempre.

+0

Grazie amico, fantastico!+ Internet per rispondere in meno di un minuto. – Will

2

è possibile utilizzare enumerate mantenere l'ind/indice degli elementi è in VM, se si effettua vm un set si avrà anche 0(1) ricerche:

vm = {-1, -1, -1, -1} 

print([ind if q in vm else 9999 for ind,ele in enumerate(vm) ]) 
+0

Sintassi fantasiosa, grazie per la condivisione, sembra molto utile! – Will

2

vostra lista comphresnion volontà, il lavoro, ma l'elenco tornerà di None perché ritorno append Nessuno:

demo:

>>> a=[] 
>>> [ a.append(x) for x in range(10) ] 
[None, None, None, None, None, None, None, None, None, None] 
>>> a 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

modo migliore per utilizzare in questo modo:

>>> a= [ x for x in range(10) ] 
>>> a 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
1
q = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5] 
vm = [-1, -1, -1, -1,1,2,3,1] 

p = [] 
for v in vm: 
    if v in q: 
     p.append(q.index(v)) 
    else: 
     p.append(99999) 

print p 
p = [q.index(v) if v in q else 99999 for v in vm] 
print p 

uscita:

[99999, 99999, 99999, 99999, 0, 1, 2, 0] 
[99999, 99999, 99999, 99999, 0, 1, 2, 0] 

Invece di usare append() nella lista di comprensione è possibile fare riferimento alla p come uscita diretta, e utilizzare q.index(v) e 99999 nel LC.

Non so se questo è intenzionale ma nota che q.index(v) troverà solo la prima occorrenza di v, anche tho si dispone di più in q. Se si desidera ottenere l'indice di tutti v in q, è consigliabile utilizzare un e una lista enumerator di già visitato indexes

Qualcosa in quelle righe (pseudo-codice):

visited = [] 
for i, v in enumerator(vm): 
    if i not in visited: 
     p.append(q.index(v)) 
    else: 
     p.append(q.index(v,max(visited))) # this line should only check for v in q after the index of max(visited) 
    visited.append(i)