2012-04-12 30 views
7

Digamos que tengo dos listas. Son listas de clasificaciones de libros en una escala de -5 a 5.Buscar índices en dos listas según la condición de elementos

Quiero saber cuando el elemento de la lista1 es >= 1 y el elemento == 0 de la lista2, por ejemplo.

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 y list2[1] = 0, quiero ser capaz de encontrar todos los diferentes índices de donde esto sucede en.

Disculpa si esto es confuso pero realmente no sé cómo decir esto.

Respuesta

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

Funcionado perfectamente, muchas gracias por la ayuda! – Mike

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

Me gusta más porque no crea una variable intermedia: las comparaciones en el filtro son directas ('list1' y' list2' están ambas allí), y más fáciles de rastrear mentalmente. No 'v' que tiene que escanear la línea para ver cómo se definió. – Izkata

2

yo encontramos este sea más legible.

>>> 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] 

Y aquí está el itertools.count doc.

+1

+1 pero ¿por qué 'count (0)' en lugar de simplemente 'count()'? También encuentro que esta es la mejor solución. – jamylak

+0

@jamylak: Legibilidad. Yo también, usaría este en mi código :) –

+0

En realidad, mirando hacia atrás en esto, creo que preferiría hacer '[i para i, (x, y) en enumerate (izip (list1, list2)) si x > = 1 e y == 0] 'en lugar de comprimir la cuenta. – jamylak

7

Otra 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

Esto es probablemente lo que habría hecho. Me gusta el hecho de que trata los dos elementos de la lista de manera similar (a diferencia de 'v' vs' list2 [i] '), pero trata el índice' i' y los elementos 'l1',' l2' un poco diferente, por lo que la sintaxis se ajusta a la semántica. – DSM

2

uso de arrays NumPy, esto es factible con la indexación lógica:

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] 

Ahora inds[0] = 0 y inds[1] = 4.

+1

'&' leería más naturalmente que '*', creo. – DSM

+0

Probablemente sea así, pero siempre me gusta pensarlo como aritmética vectorial en una matriz de booleanos. Pero es bueno asegurarse de que la gente sepa que existen ambas opciones. – ely

+0

Ahora que lo pienso, '== True' es innecesario, ¿no? – DSM

Cuestiones relacionadas