16 votos

Seleccionar entidades por atributo si en la lista de Python

Creo que esto será en gran medida una sintaxis sql pregunta. Esencialmente, estoy tratando de completar un seleccionar por atributos en Python, pero basado en la consulta de si el atributo está presente en una lista.

Una consulta en su forma más simple debe ser algo como esto:

qry = " \"OBJECTID\" in oid_list"
arcpy.SelectLayersByAttribute_management(inft, "NEW_SELECTION", qry)

pero ese método devuelve un no válido error de expresión.

En el pasado, he tenido que usar más complicado sytax para este tipo de consulta, tales como:

sqlQuery2 = "nid in (" + ','.join(["'"+x+"'" for x in delta_list]) +")"

pero una adaptación de este fragmento no parece funcionar para mí, es decir.:

 "OBJECTID_1 in (" + ','.join(["'"+str(x)+"'" for x in oid_list]) +")"

Así, me refiero a que expertos de SQL: ¿tienes alguna sugerencia? Lo que me estoy perdiendo aquí?

20voto

hernan43 Puntos 566

La consulta original podría haber sido modificado para obtener una lista de números enteros:

'"OBJECTID_1" IN ' + str(tuple(oid_list))

así que si oid_list = [7, 9, 4, 8], entonces el resultado es:

"OBJECTID_1" IN (7, 9, 4, 8)

Tenga en cuenta que si la lista de la longitud es cero o uno, las tuplas () y (7,) será errores de sintaxis. Así que este truco sólo funciona para las listas de dos o más miembros.

Ver más técnicas para convertir una lista a una cadena separada por comas aquí, como este:

'"OBJECTID_1" IN (' + ','.join(map(str, oid_list)) + ')'

10voto

auramo Puntos 161

Esta es una versión ligeramente modificada de la función en esta respuesta, para aceptar una lista de Python en lugar de una cadena delimitada por punto y coma:

 def buildWhereClauseFromList(table, field, valueList):
    """Takes a list of values and constructs a SQL WHERE
    clause to select those values within a given field and table."""

    # Add DBMS-specific field delimiters
    fieldDelimited = arcpy.AddFieldDelimiters(arcpy.Describe(table).path, field)

    # Determine field type
    fieldType = arcpy.ListFields(table, field)[0].type

    # Add single-quotes for string field values
    if str(fieldType) == 'String':
        valueList = ["'%s'" % value for value in valueList]

    # Format WHERE clause in the form of an IN statement
    whereClause = "%s IN(%s)" % (fieldDelimited, ', '.join(map(str, valueList)))
    return whereClause
 

6voto

wonderfulthunk Puntos 182

Creo que el enfoque más sencillo para esto es para iterar a través de los valores en su lista de singular y agregarlos a la selección (de Modo que puede cambiar tu consulta con cada valor de la lista). Algo como esto:

oidList = [1,2,3,4]
arcpy.management.MakeFeatureLayer(thisFC,thisLyr)
for values in oidList:
    query = "\"OBJECTID\"="+str(values)
    arcpy.management.SelectLayerByAttribute(thisLyr,"ADD_TO_SELECTION",query)

Usted puede utilizar el ADD_TO_SELECTION incluso si no hay características seleccionadas, va a crear una nueva selección en la primera iteración.

Editar:

Si usted piensa que el coste de la actividad individual SelectLayerByAttribute será demasiado alto, usted podría utilizar un enfoque como este donde puede crear una muy amplia selección cláusula dependiendo de su lista de longitud:

oidList = [1,2,3,4]
arcpy.management.MakeFeatureLayer(thisFC,thisLyr)
query=""
q=""
oidList.sort()
for x in oidList:
    query="\"OBJECTID\"="+str(x)+" OR "+q
    q=query
q=q[1:-4]
arcpy.management.SelectLayerByAttribute(thisLyr,"NEW_SELECTION",q)

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X