2011-04-13 10 views
9

Supongamos que tengo una lista de listas o una lista de tuplas, lo que sea que pueda resolver mi problema de manera más eficiente. Por ejemplo:Usando Python, ¿cómo encontrar elementos en una lista de listas basada en una clave que es un elemento de la lista interna?

student_tuples = [ 
    ('john', 'A', 15), 
    ('jane', 'B', 12), 
    ('dave', 'B', 10), 
] 

La tarea es encontrar un elemento en la lista principal basado en una clave que es cualquier elemento de la lista o tupla interior. Por ejemplo:

Utilizando la lista anterior:

find(student_tuples, 'A') 

o

find(student_tuples, 15) 

sería tanto volver

('john', 'A', 15) 

Busco un método eficiente.

+0

Usted debe considerar la posibilidad de una clase 'Student' y tener su lista de los estudiantes contienen instancias de esa clase. – Daenyth

Respuesta

13

me gustaría utilizar filter() o una lista de comprensión.

def find_listcomp(students, value): 
    return [student for student in students if student[1] == value or student[2] == value] 

def find_filter(students, value): 
    return filter(lambda s: s[1] == value or s[2] == value, students) 
+0

Puede mejorar esto cambiando el valor de retorno a: devolver [estudiante para estudiantes en estudiantes si valor en estudiante]. De lo contrario, solo devolverá un acierto para los valores segundo y tercero en la tupla. –

+0

@bigmattyh: Eso devolvería '('john' ...)' si 'value == 'john'', que no es lo que OP quiere. – Daenyth

+0

Dijo: "La tarea es encontrar un elemento en la lista principal basado en una clave que sea ** cualquier elemento de la lista interna o tupla **." –

4

Para encontrar el primer partido solamente, puede utilizar

def find(list_of_tuples, value): 
    return next(x for x in list_of_tuples if value in x) 

Esto elevará StopIteration si no se encuentra ningún registro coincidente. Para elevar una excepción más apropiado, puede utilizar

def find(list_of_tuples, value): 
    try: 
     return next(x for x in list_of_tuples if value in x) 
    except StopIteration: 
     raise ValueError("No matching record found") 
0

Esta función devolverá una lista de las tuplas que contienen su término de búsqueda. Aquí van:

def find_in_tuples(tuples, term): 
    matching_set = [] 
    for tuple in tuples: 
     if term in tuple: 
      matching_set.append(tuple) 
    return matching_set 

>>> find_in_tuples(student_tuples, 'A') 
[('john', 'A', 15)] 
>>> find_in_tuples(student_tuples, 'B') 
[('jane', 'B', 12), ('dave', 'B', 10)] 
4

Puede utilizar listas por comprensión del pitón para seleccionar y filtro:

def find(tuples, term): 
    return [tuple for tuple in tuples if term in tuple] 
+1

Me gusta este, pero tiene un error tipográfico: 'if term in tuples' should be 'if term in tuple' – kadam

+0

@kadam reparado, gracias! – sverre

+0

como he comentado en la solución de @Daenyth, combinaré los dos. Ambas respuestas son buenas, acepté la otra porque llegó antes. – kadam

Cuestiones relacionadas