2012-04-12 14 views
7

Diciamo che ho due elenchi. Si tratta di elenchi di classificazioni di libri su una scala da -5 a 5.Trova indici su due elenchi in base agli articoli condizione

Voglio sapere quando l'elemento di list1 è >= 1 e l'elemento di list2 == 0, ad esempio.

list1 = [3, 3, 1, 0, 3, 0, 3, 0, 0, -3, 0, 5, 3, 0, 1, 0, 0, 5, 3, 0, 0, 0, 0, 1, 0, 3, 0, 1, 0, 0, 3, 5, 3, 3, 0, 0, 0, 5, 0, 5, 0, 3, 3, 0, -3, 0, 0, 5, 1, 5, 3, 0, 3, 0, 0] 
list2 = [5, 0, 0, 0, 0, 0, 5, 0, 0, 1, 0, 5, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 5, 5, 5, 3, 0, 0, 0, 3, 0, 0, 0, 5, 3, 0, 0, 0, 0, 5, 0, 5, 3, 0, 0, 0, 0] 

list1[1] = 3 e list2[1] = 0, voglio essere in grado di trovare tutti i diversi indici di cui questo avviene a.

Scusate se questo è fonte di confusione ma non so davvero in quale altro modo di esprimere questo.

risposta

11
>>> [i for i, v in enumerate(list1) if v>=1 and list2[i]==0] 
[1, 2, 4, 14, 18, 27, 39, 48, 52] 
+0

Ha funzionato perfettamente, grazie mille per l'aiuto! – Mike

4
>>>idx_list = [i for i in range(len(list1)) if list1[i] > 1 and list2[i] == 0] 
+0

Mi piace di più perché non crea una variabile intermedia - i confronti nel filtro sono diretti ('list1' e' list2' ci sono entrambi) e più facile da seguire mentalmente. No 'v' che devi scansionare la linea per vedere come è stata definita. – Izkata

2

ho trovato questo più leggibile.

>>> from itertools import count 
>>> [i for i,one,two in zip(count(0), list1, list2) if one >= 1 and two == 0] 
[1, 2, 4, 14, 18, 27, 39, 48, 52] 

Ed ecco lo itertools.count doc.

+1

+1 ma perché avere 'count (0)' invece di solo 'count()'? Inoltre trovo che questa sia la soluzione migliore. – jamylak

+0

@jamylak: leggibilità. Anch'io, userei questo nel mio codice :) –

+0

In realtà ripensandoci penso che preferisco fare '[i for i, (x, y) in enumerate (izip (list1, list2)) se x > = 1 and y == 0] 'invece del conteggio zippato. – jamylak

7

Un'altra variante:

>>> [i for i, (l1, l2) in enumerate(zip(list1, list2)) if l1 >= 1 and l2 == 0] 
[1, 2, 4, 14, 18, 27, 39, 48, 52] 
+1

Questo è probabilmente quello che avrei fatto. Mi piace il fatto che tratti i due elementi della lista in modo simile (a differenza di 'v' vs' list2 [i] '), ma tratta l'indice' i' e gli elementi 'l1',' l2' un po 'diversamente, quindi la sintassi si adatta alla semantica – DSM

2

Uso degli array NumPy, questo è fattibile con indicizzazione logico:

import numpy as np 
list1 = np.array([1, -1, 0, 0, 1]) 
list2 = np.array([0, 5, 0, 0, 0]) 

# Option 1, multiply the logicals together. 
inds = np.where((list1 >= 1)*(list2 == 0))[0] 

# Option 2, pure logicals. 
inds = np.where((list1 >= 1) & (list2 == 0))[0] 

Ora inds[0] = 0 e inds[1] = 4.

+1

'e' leggerebbe più naturalmente di '*', penso. – DSM

+0

Probabilmente sì, ma mi piace sempre pensarlo come aritmetica vettoriale su una serie di booleani. Ma è bene assicurarsi che la gente sappia che entrambe le opzioni esistono. – ely

+0

Vieni a pensarci, '== True' non è necessario, no? – DSM

Problemi correlati