I have a source polyline feature class and a target polyline feature class. Eventually, I want to replace the target feature geometry with the source feature geometry while preserving existing attributes in the target feature. In the code below, I am trying just to print values based on a condition that looks at a fieldname in the target class. The code runs without error but does not output or print anything (I expected it to find both string values in my list). Any ideas? import arcpy

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]

sourcelayer = arcpy.mapping.Layer('sourcelayer')
targetlayer = arcpy.mapping.Layer('targetlayer')

d1 = {}

with arcpy.da.SearchCursor("sourcelayer", ["OID@","STICK_ID", "SHAPE@"]) as curs:
    stIdCount = 0
    pointCount = 0
    for stId in curs:
        #update dictionary
        #da.[stId[1], [])
        stIdCount += 1
        stickid = str(stId[1])
        print "\n"
        print ("\t"*4), stickid
        for point in stId[2].getPart(0):
            pointCount += 1
            print str(stickid), "    ", point.X, " ", point.Y
            d1.setdefault(key, []).append([point.X, point.Y])
print "\n", "Total: {0} wellsticks and {1} vertices".format(stIdCount, pointCount), "\n"
  • 2
    Are you running this from a script tool? You may need to use arcpy.AddMessage() instead of print. e.g. arcpy.AddMessage("{0}, {1}".format(point.X, point.Y))
    – Midavalo
    Commented Oct 24, 2017 at 22:25
  • 1
    shouldn't it be if targetStickID[0] in ["W2377","W2378"]:? but it wont as the wildcard 'STICK_ID' isn't even similar to "W2377" or "W2378" so you're never entering the block. row[1].getPart(0) will cause this to fall over, it's row[2].getPart(0) to obtain the geometry [0]=OID, [1]=STICK_ID, [2]=SHAPE@. Consider using a with block for your cursor, I can't see you del cursor anywhere and that could leave a lock on your feature class. Commented Oct 24, 2017 at 22:30
  • I am now able to create a dictionary and set all STICK_ID as key and all multiple vertices for each STICK_ID as an array of X,Y coordinates in the values.
    – Chris
    Commented Oct 26, 2017 at 19:10

2 Answers 2


This line returns a list of field names with STICK_ID as part of their name:

targetStickID = [t.name for t in arcpy.ListFields(targetlayer,"STICK_ID")]

Thus, this line will never return True:

if ["W2377","W2378"] in targetStickID:

Rework this logic to accomplish whatever it is this line is supposed to be doing.

Also, you're looking for a list within a list in the above line. You might mean instead:

if "W2377" in targetStickID or "W2378" in targetStickID:
  • You would need to make it arcpy.ListFields(targetlayer,"*STICK_ID*") as without the asterisks the field name must exactly match STICK_ID which would mean W2377 or W2378 could never be in the field name. Commented Oct 24, 2017 at 23:39
  • @MichaelStimson I have a hunch STICK_ID is the field name and W2377 and W2378 are field values. Commented Oct 25, 2017 at 1:52
  • That's not how the code reads. I suppose we're just guessing what that whole line is about because it's not obvious what the OP is trying to achieve. Commented Oct 25, 2017 at 2:25
  • @MichaelStimson Yes, STICK_ID is the fieldname and W2377 & W2378 are values I want to match up. STICK_ID is the matching/join column in both sourcelayer & targetlayer feature classes. I want to obtain all vertices in sourcelayer, remember the STICK_ID, and if that same STICK_ID is found in targetlayer, replace the geometry in targetlayer with that of sourcelayer.
    – Chris
    Commented Oct 25, 2017 at 13:22

Create a dictionary from your source layer with stick ID's as your key and geometries as your values. Then use an update cursor on the target feature class to update those ID's with the source feature's geometries.

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]

#empty dictionary for housing geometries
geomDi = {}
#source feature classcursor with geometry and ID
with arcpy.da.SearchCursor ("sourcelayer", ["STICK_ID", "SHAPE@"]) as curs:
    for stId, geom in curs:
        #update dictionary
        geomDi [stId] = geom

#update cursor target feature class
with arcpy.da.UpdateCursor ("targetlayer", ["STICK_ID", "SHAPE@"]) as curs:
    for stId, geom in curs:
        #pull geometry if ID was found in first cursor
        try: geom = geomDi [stId]
        #not found in first cursor - continue
        except KeyError: continue

        #update row
        row = (stId, geom)
        curs.updateRow (row)
  • #source feature classcursor with geometry and ID with arcpy.da.SearchCursor ("sourcelayer", ["STICK_ID", "SHAPE@"]) as curs: #iterate for geom, stId in curs: #update dictionary di [stId] = geom Should the variables be switched around to read: for stId, geom in curs: #update dictionary geomDi [stId] = geom
    – Chris
    Commented Oct 25, 2017 at 17:38
  • What do the brackets [] do in the cursor line when wrapped around "STICK_ID", "SHAPE@"? I've tried manipulating the code to print each vertice's X,Y but to no avail. I appreciate all the help so far. To better explain, I want to obtain the X,Y for every vertice in every line so that I can cross-reference it based on a UID in another feature class and if found, replace with new vertices. This is a way to update multiple polylines that were incorrectly created in my targetlayer with accurate polylines existing in my sourcelayer.
    – Chris
    Commented Oct 25, 2017 at 22:15
  • The first part of this code seems to keep adding the list of STICK_ID to the keys in geomDi{}. I do not believe this is working properly.
    – Chris
    Commented Oct 26, 2017 at 14:45
  • There was a mistake in the code. I've updated. Commented Oct 27, 2017 at 17:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.