por - metodos de listas en python
Cómo sangrar las listas de Python-comprensiones? (7)
Depende de cuánto tiempo son. Tiendo a estructurarlos así:
[x.id for x
in self.db.query(schema.allPostsUuid).execute(timeout=20)
if x.type == ''post''
and x.deleted is not False
and ...
and ...]
De esta forma, cada expresión tiene su propia línea.
Si alguna línea se vuelve demasiado grande, me gusta extraerla en una lambda o expresión:
transform = lambda x: x.id
results = self.db.query(schema.allPostsUuid).execute(timeout=20)
condition = lambda x: x.deleted is not False and ... and ...
[transform(x) for x in results if condition(x)]
Y luego, si un lambda se vuelve demasiado largo, se promueve a una función.
Las listas de comprensión pueden ser útiles en ciertas situaciones, pero también pueden ser bastante horribles de leer. Como un ejemplo ligeramente exagerado, ¿cómo sangraría lo siguiente?
allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) if x.type == "post" and x.deleted is not False]
Donde trabajo, nuestras pautas de codificación nos harían hacer algo como esto:
all_posts_uuid_query = self.db.query(schema.allPostsUuid)
all_posts_uuid_list = all_posts_uuid_query.execute(timeout=20)
all_uuid_list = [
x.id
for x in all_posts_uuid_list
if (
x.type == "post"
and
not x.deleted # <-- if you don''t care about NULLs / None
)
]
Para mí eso es demasiado. Tal vez es solo un ejemplo terrible, ya que "tipo" y "eliminado" serían claramente parte de la consulta db.
Tiendo a pensar que si una lista de comprensión abarca múltiples líneas, probablemente no debería ser una lista de comprensión. Habiendo dicho eso, por lo general solo lo divido en "si" como lo han hecho otras personas y responderé aquí.
Qué tal si:
allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20)
if (x.type == "post" and x.deleted is not False)]
En general, las líneas largas pueden evitarse calculando previamente las subexpresiones en variables, lo que puede agregar un costo de rendimiento minúsculo:
query_ids = self.db.query(schema.allPostsUuid).execute(timeout = 20)
allUuids = [x.id for x in query_ids
if (x.type == "post" and x.deleted is not False)]
Por cierto, ¿no is not False
superfluo '' is not False
''? ¿Te preocupa diferenciar entre Ninguno y Falso? Porque de lo contrario, es suficiente dejar la condición como única: i f (x.type == "post" and x.deleted)
allUuids = [x.id
for x in self.db.query(schema.allPostsUuid).execute(timeout = 20)
if x.type == "post" and x.deleted is not False]
No deberías usar una lista de comprensión para eso .
Las listas de comprensión son una característica increíble, pero están destinadas a ser accesos directos, no un código normal.
Para un fragmento tan largo, debe usar bloques comunes:
allUuids = []
for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) :
if x.type == "post" and x.deleted is not False :
allUuids.append(x.id)
Exactamente el mismo comportamiento, mucho más legible. Guido estaría orgulloso de ti :-)
Si tienes una comprensión, la respuesta de Orestis es buena.
Para comprensiones más complejas como esa, sugeriría usar un generador con yield
:
allUuids = list(self.get_all_uuids())
def get_all_uuids(self):
for x in self.db.query(schema.allPostsUuid).execute(timeout = 20):
if x.type == "post" and x.deleted is not False:
yield x.id