resueltos poo importar herencia ejercicios ejemplos ejemplo crear constructores clases clase python arrays iteration

poo - Usar ''in'' para hacer coincidir un atributo de los objetos de Python en una matriz



poo python 3 (8)

No recuerdo si estaba soñando o no, pero me parece recordar que hay una función que permite algo así como,

foo in iter_attr(array of python objects, attribute name)

He revisado los documentos, pero este tipo de cosas no entran en ningún encabezado enumerado obvio


¿Estás buscando obtener una lista de objetos que tienen cierto atributo? Si es así, una lista de comprensión es la forma correcta de hacerlo.

result = [obj for obj in listOfObjs if hasattr(obj, ''attributeName'')]


Creo:

#!/bin/python bar in dict(Foo)

Es en lo que estás pensando. Al intentar ver si existe una determinada clave dentro de un diccionario en python (la versión de Python de una tabla hash), hay dos maneras de verificar. Primero está el método has_key() adjunto al diccionario y el segundo es el ejemplo dado arriba. Devolverá un valor booleano.

Eso debería responder a su pregunta.

Y ahora un poco fuera del tema para vincular esto a la lista de respuesta de comprensión dada previamente (para un poco más de claridad). List Comprehensions construye una lista a partir de un bucle for con modificadores. Como ejemplo (para aclarar un poco), una forma de usar el constructo de lenguaje in dict en una lista de comprensión :

Supongamos que tiene un diccionario bidimensional foo y solo desea los diccionarios de segunda dimensión que contienen la bar teclas. Una forma relativamente sencilla de hacerlo sería usar una lista de comprensión con un condicional de la siguiente manera:

#!/bin/python baz = dict([(key, value) for key, value in foo if bar in value])

Tenga en cuenta la if bar in value en el final de la declaración **, esta es una cláusula modificadora que le dice a la lista de comprensión que solo conserve esos pares clave-valor que cumplen condicionalmente. ** En este caso, baz es un nuevo diccionario que contiene solo los diccionarios de foo que contienen barra (afortunadamente no me perdí nada en ese ejemplo de código ... es posible que tengas que echar un vistazo a la lista de documentación de comprensión encontrada en los tutoriales de docs.python.org y en secnetix.de , ambos los sitios son buenas referencias si tiene preguntas en el futuro).


Lo que estaba pensando se puede lograr usando listas de comprensión, pero pensé que había una función que lo hizo de una manera un poco más ordenada.

es decir, ''barra'' es una lista de objetos, todos los cuales tienen el atributo ''id''

La forma mítica funcional:

foo = 12 foo in iter_attr(bar, ''id'')

La lista de manera de comprensión:

foo = 12 foo in [obj.id for obj in bar]

En retrospectiva, la lista de comprensión es bastante ordenada de todos modos.


Si planeas buscar algo de tamaño remotamente decente, tu mejor opción será usar un diccionario o un conjunto. De lo contrario, básicamente tiene que recorrer cada elemento del iterador hasta llegar al que desea.

Si esto no es necesariamente un código sensible al rendimiento, la forma de comprensión de la lista debería funcionar. Pero tenga en cuenta que es bastante ineficiente porque repasará todos los elementos del iterador y luego volverá sobre él hasta que encuentre lo que quiere.

Recuerde, Python tiene uno de los algoritmos de hash más eficientes. Úselo para su ventaja.


siempre puedes escribir uno tú mismo:

def iterattr(iterator, attributename): for obj in iterator: yield getattr(obj, attributename)

funcionará con cualquier cosa que itere, ya sea una tupla, lista o lo que sea.

Me encanta Python, hace cosas como esta muy simples y no más complicadas de lo necesario, y en uso cosas como esta son muy elegantes.


Usar una lista de comprensión crearía una lista temporal, que podría consumir toda tu memoria si la secuencia que se busca es grande. Incluso si la secuencia no es grande, construir la lista significa iterar sobre toda la secuencia antes in pueda comenzar su búsqueda.

La lista temporal puede evitarse mediante el uso de una expresión de generador:

foo = 12 foo in (obj.id for obj in bar)

Ahora, siempre que obj.id == 12 cerca del inicio de la bar , la búsqueda será rápida, incluso si la bar es infinitamente larga.

Como @Matt sugirió, es una buena idea usar hasattr si alguno de los objetos en la bar puede estar perdiendo un atributo de id :

foo = 12 foo in (obj.id for obj in bar if hasattr(obj, ''id''))


La función en la que estás pensando es probablemente operator.attrgettter . Por ejemplo, para obtener una lista que contiene el valor del atributo "id" de cada objeto:

import operator ids = map(operator.attrgetter("id"), bar)

Si desea comprobar si la lista contiene un objeto con una identificación == 12, entonces una manera ordenada y eficiente (es decir, no iterar toda la lista innecesariamente) es:

any(obj.id == 12 for obj in bar)

Si desea usar ''in'' con attrgetter, mientras retiene la iteración diferida de la lista:

import operator,itertools foo = 12 foo in itertools.imap(operator.attrgetter("id"), bar)


No, no estabas soñando. Python tiene un excelente sistema de comprensión de listas que le permite manipular listas de forma muy elegante, y dependiendo de exactamente lo que quiere lograr, esto se puede hacer de varias maneras. Básicamente, lo que está haciendo es decir "Para el elemento en la lista si criteria.matches", y de eso puede simplemente iterar a través de los resultados o volcar los resultados en una nueva lista.

Voy a cibear un ejemplo de Dive Into Python aquí, porque es bastante elegante y son más inteligentes que yo. Aquí obtienen una lista de archivos en un directorio y luego filtran la lista de todos los archivos que coinciden con un criterio de expresión regular.

files = os.listdir(path) test = re.compile("test/.py$", re.IGNORECASE) files = [f for f in files if test.search(f)]

Puedes hacer esto sin expresiones regulares, para tu ejemplo, para cualquier cosa donde tu expresión al final devuelva verdadero para una coincidencia. Hay otras opciones como usar la función filter (), pero si fuera a elegir, iría con esto.

Eric Sipple