Supongamos que estoy creando una clase simple para que funcione de manera similar a una estructura de estilo C, solo para contener elementos de datos. Estoy tratando de averiguar cómo buscar en una lista de objetos objetos con un atributo que iguale un cierto valor. A continuación se muestra un ejemplo trivial para ilustrar lo que estoy tratando de hacer.
Por ejemplo:
class Data:
pass
myList = []
for i in range(20):
data = Data()
data.n = i
data.n_squared = i * i
myList.append(data)
¿Cómo buscaría en la lista myList para determinar si contiene un elemento con n == 5?
He estado buscando en Google y buscando los documentos de Python, y creo que podría hacer esto con una lista de comprensión, pero no estoy seguro. Debo agregar que, por cierto, tengo que usar Python 2.4.3, por lo que las nuevas funciones gee-whiz 2.6 o 3.x no están disponibles para mí.

Respuestas:
Puede obtener una lista de todos los elementos coincidentes con una lista de comprensión:
[x for x in myList if x.n == 30] # list of all elements with .n==30Si simplemente desea determinar si la lista contiene algún elemento que coincida y hacerlo (relativamente) eficientemente, puede hacerlo
def contains(list, filter): for x in list: if filter(x): return True return False if contains(myList, lambda x: x.n == 3) # True if any element has .n==3 # do stufffuente
Simple, elegante y potente:
Una expresión generadora en conjunción con un incorporado… (python 2.5+)
any(x for x in mylist if x.n == 10)Utiliza la función
any()incorporada de Python , que se define de la siguiente manera:def any(iterable): for element in iterable: if element: return True return Falsefuente
any(x for x in mylist if x['n'] == 10)pero es una buena ideaSolo para completar, no olvidemos la cosa más simple que posiblemente podría funcionar:
for i in list: if i.n == 5: # do something with it print "YAY! Found one!"fuente
[x for x in myList if x.n == 30] # list of all matches [x.n_squared for x in myList if x.n == 30] # property of matches any(x.n == 30 for x in myList) # if there is any matches [i for i,x in enumerate(myList) if x.n == 30] # indices of all matches def first(iterable, default=None): for item in iterable: return item return default first(x for x in myList if x.n == 30) # the first match, if anyfuente
filter(lambda x: x.n == 5, myList)fuente
lambdas.Puede usar
inpara buscar un elemento en una colección y una lista de comprensión para extraer el campo que le interesa. Esto (funciona para listas, conjuntos, tuplas y cualquier cosa que defina__contains__o__getitem__).if 5 in [data.n for data in myList]: print "Found it"Ver también:
fuente
Debe agregar un método
__eq__y un__hash__a suDataclase, podría verificar si el__dict__atributos son iguales (las mismas propiedades) y luego si sus valores también son iguales.Si hiciste eso, puedes usar
test = Data() test.n = 5 found = test in myListLa
inpalabra clave comprueba sitestestá enmyList.Si solo desea una
npropiedadData, puede usar:class Data(object): __slots__ = ['n'] def __init__(self, n): self.n = n def __eq__(self, other): if not isinstance(other, Data): return False if self.n != other.n: return False return True def __hash__(self): return self.n myList = [ Data(1), Data(2), Data(3) ] Data(2) in myList #==> True Data(5) in myList #==> Falsefuente
Considere usar un diccionario:
myDict = {} for i in range(20): myDict[i] = i * i print(5 in myDict)fuente
Otra forma de hacerlo es usando la función next ().
matched_obj = next(x for x in list if x.n == 10)fuente