Adding to a Selection

788
10
Jump to solution
09-07-2017 10:54 AM
JoeBorgione
MVP Esteemed Contributor

Python hack (at best) here....

I would like to base a selection on an already selected record in a layer, and can't quite seem to crack that nut.  Here is the pseudo code:

Select a record  ' in this case a point

Extract the FullStreet attribute value  ' it'll be something like S MAIN ST

Add to the selection all other points that have that same FullStreet field value   'seems like a fairly simple operation

I've been trying to do that using an arcpy.SearchCursor  within the arcpy window :

>>> cursor = arcpy.SearchCursor("apLayer")
>>> for row in cursor:
... street = row.FullStreet
... arcpy.SelectLayerByAttribute_management ("apLayer","ADD_TO_SELECTION","FullStreet = 'street'")
...

>>>

This runs with no errors but only ends up with the originally selected point as being selected.  (See attached)

Questions:  is this a case of newbie syntax error?

                    is there a better approach to do what I intend to do?  

That should just about do it....
0 Kudos
1 Solution

Accepted Solutions
curtvprice
MVP Esteemed Contributor

You are messing with the selection on a layer while it's open. Even if you get the expression right I think it may not work right.

I think the following will do what you want and seems wiser to me. (Also, arcpy.da.SearchCursor is much faster than the old flavor)

# collect street names from selected points 
# (works with one or more selected features)
with arcpy.da.SearchCursor("aplayer", "FullStreet") as rows:
    streets = [row[0] for row in rows]
# cursor closes when we leave the with block
# convert to a string list for our select expression
street_list = ",".join(["'{}'".format(s) for s in streets]) 
# street_list will look like: "'E MAIN', 'W MAIN'"
where = "FullStreet IN ({})".format(street_list)
# add all points with these street names to the selected set
arcpy.SelectLayerByAttribute_management ("apLayer",
                                         "ADD_TO_SELECTION",
                                         where)
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

10 Replies
RebeccaStrauch__GISP
MVP Esteemed Contributor

Are you creating a feature layer first?  Look at the sample for a subset of a selection in the help

Select Layer By Attribute—Help | ArcGIS for Desktop 

It doesn't use a cursor, but might give you some other help.

JoeBorgione
MVP Esteemed Contributor

Yes, I'm working against a layer which is another source of bewilderment to me.  The documentation says that arcpy.SelectLayerByAttribute_management only works  against layers and not feature classes.  However, I've run it against both (outside of a cursor) and had it work when I hard code the FullStreet value like this:

arcpy.SelectLayerByAttribute_management ("apLayer","ADD_TO_SELECTION","FullStreet = 'S BOX ELDER ST'")

That should just about do it....
0 Kudos
DarrenWiens2
MVP Honored Contributor

"FullStreet = 'street'" looks for the literal string 'street', and since you probably don't have any records where the value is 'street', nothing gets added.

You need to substitute the variable value into your query, which gets a little complicated with the quotes. Basically, it should be something like: "FullStreet = '" + street + "'" (but you may have to play around with the quoting situation).

RebeccaStrauch__GISP
MVP Esteemed Contributor
JoshuaBixby
MVP Esteemed Contributor

When I run Select Layer By Attribute directly against a feature class, it generates an error:  "Parameters are not valid. The value cannot be a feature class."  Can you elaborate more on how you run it directly against a feature class?

0 Kudos
JoeBorgione
MVP Esteemed Contributor

Darren Wiens‌ & Rebecca Strauch, GISP‌  

Darren and Rebecca-  Thank you both for your suggestions;  I got dragged into an endless meeting that finally did end and I haven't had a chance yet to chase down the quotes thing and the links you two provided.  Thanks in advance!!

That should just about do it....
0 Kudos
curtvprice
MVP Esteemed Contributor

You are messing with the selection on a layer while it's open. Even if you get the expression right I think it may not work right.

I think the following will do what you want and seems wiser to me. (Also, arcpy.da.SearchCursor is much faster than the old flavor)

# collect street names from selected points 
# (works with one or more selected features)
with arcpy.da.SearchCursor("aplayer", "FullStreet") as rows:
    streets = [row[0] for row in rows]
# cursor closes when we leave the with block
# convert to a string list for our select expression
street_list = ",".join(["'{}'".format(s) for s in streets]) 
# street_list will look like: "'E MAIN', 'W MAIN'"
where = "FullStreet IN ({})".format(street_list)
# add all points with these street names to the selected set
arcpy.SelectLayerByAttribute_management ("apLayer",
                                         "ADD_TO_SELECTION",
                                         where)
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
JoeBorgione
MVP Esteemed Contributor

Joshua BixbyCurtis Price

Joshua-  all I can say is it's probably dumb luck that I can get it to work directly upon a feature class.  However, it may be (if I understand Curtis' reply) the fact that I'm working in the python window in an ArcMap session with the feature class right there and available for reading.  See attached screen cap.

Curtis-  thanks for your insight.  Let me mess with your suggested code.  I kind of figured that the arcpy.da cursor would show up in the conversation sooner or later;  I'll work with it.

eta:  the Curtis code works quite nicely.  See attached success.png  (For good practice I'm hitting a layer instead of the feature class itself and using the arcpy.da cursor.)

That should just about do it....
0 Kudos
DarrenWiens2
MVP Honored Contributor

Because you're running this in ArcMap, even though the underlying dataset is a feature class, you are referencing the feature layer. If you reference the feature class by including the full path rather than the feature layer name, you should get the error Joshua mentions.