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==30
Si 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 stuff
fuente
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 False
fuente
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 any
fuente
filter(lambda x: x.n == 5, myList)
fuente
lambda
s.Puede usar
in
para 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 suData
clase, 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 myList
La
in
palabra clave comprueba sitest
está enmyList
.Si solo desea una
n
propiedadData
, 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 #==> False
fuente
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