Listas por comprensión en PyQGIS

En posts anteriores (1, 2) ya se ha contemplado el uso de listas por comprensión en PyQGIS. Éstas permiten simplificar el código y hacerlo más legible a la hora de programar. En esta oportunidad consideraré la comparación entre la forma clásica de trabajar y la comprensiva y la producción de listas anidadas por comprensión que requieren ser aplanadas (“flattened”).

El código siguiente realiza la primera labor y no requiere capas activas en la Map Legend porque la lista de coordenadas para crear los QgsPoint está dentro de éste. Observe que la función que usa la lista por comprensión, ‘createQgsPoints2’, se circunscribe a una sola línea.

def createQgsPoints1(coor):
   
    points = []

    for i in range(0, len(coor) , 2):
        point = QgsPoint(coor[i], coor[i+1])
        points.append( point )
 
    return points
    
def createQgsPoints2(coor):
    
    return [QgsPoint(coor[i], coor[i+1]) for i in range(0, len(coor) , 2) ]

#Code starts here

coor = [406335.6687754134, 4432940.063864975, 
        394017.75852265005, 4440393.867971825, 
        430156.47136697, 4454641.599921007, 
        421978.8651792078, 4435913.523100217, 
        401371.25949762185, 4448710.306960685, 
        429328.7574991899, 4440607.991737985, 
        396034.804120831, 4427616.105982565, 
        412764.44655418996, 4451222.183762893, 
        394352.97778292216, 4445916.67530414, 
        388347.80472881417, 4440362.656937134]

#classic list
print createQgsPoints1(coor)

#comprehension list
print createQgsPoints2(coor)

La ejecución del código anterior produce listas idénticas de QgsPoint por lo que la lista por comprensión tiene la sintaxis adecuada.

[(406336,4.43294e+06), (394018,4.44039e+06), 
(430156,4.45464e+06), (421979,4.43591e+06), 
(401371,4.44871e+06), (429329,4.44061e+06), 
(396035,4.42762e+06), (412764,4.45122e+06), 
(394353,4.44592e+06), (388348,4.44036e+06)]

[(406336,4.43294e+06), (394018,4.44039e+06), 
(430156,4.45464e+06), (421979,4.43591e+06), 
(401371,4.44871e+06), (429329,4.44061e+06), 
(396035,4.42762e+06), (412764,4.45122e+06), 
(394353,4.44592e+06), (388348,4.44036e+06)]

Para el código siguiente se requiere una capa activa. La función ‘generateCoor’ usa una lista anidada por comprensión. El anidamiento sustituye a dos instrucciones con ‘append’ y es necesario el anidamiento (se puede usar también tuplas o diccionarios) para evitar errores de ejecución. Sin embargo, como lo que nos interesa como salida es una lista simple se recurre al “flattened” (return en la función ‘generateCoor’).

import random

def generateCoor(number_points, extent):
    
    tmp = [[random.uniform(extent.xMinimum(), extent.xMaximum()), 
            random.uniform(extent.yMinimum(), extent.yMaximum())] 
            for i in range(number_points)]
        
    return [num for elem in tmp for num in elem]

layer = iface.activeLayer()

extent = layer.extent()

print generateCoor(10, extent)

Cuando se ejecuta el código anterior con la ráster layer (la capa puede ser también vectorial) de la imagen siguiente:

raster

se obtiene esta lista de valores de coordenadas (x,y) que corresponden a puntos que están comprendidos dentro de la extensión del ráster:

[390617.36801198736, 4439209.311542905, 
421159.8252370954, 4457102.600586147, 
390599.75215229864, 4456796.948595617, 
423886.06920312135, 4420221.387873261, 
451689.14695124107, 4432014.500144213, 
360083.62912076514, 4426851.277487717, 
471375.69931530836, 4420551.647859029, 
454210.8677663581, 4452179.206169682, 
424273.43670549593, 4466637.802840466, 
436775.01637955103, 4432895.319724681]

El proceso completo de la creación de una memory layer con coordenadas de este tipo, donde se usa una lista clásica en lugar de una por compresión, puede observarse en este post:

Función en PyQGIS para crear una memory layer de puntos aleatorios.

Nota: Los puntos anteriores no pueden reproducirse porque son aleatorios y serán diferentes cada vez que se ejecute el código.

Esta entrada fue publicada en PyQGIS, QGIS, SIG, Software Libre. Guarda el enlace permanente.

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s