How to create a shapefile from a python list using ArcPy?

2003
12
04-22-2014 07:07 AM
ArielleSimmons
New Contributor
I've been looking for a way to create a shapefile from a python list (in the case below, uniqueList).

Basically, I have been using SearchCursor's to iterate through a shapefile, and I would like to export the result as a shapefile...I tried CopyFeatures...but it didn't even return a blank file (it returned nothing).

import arcpy

def find_overlaps(input_features, output_features):
   uniqueList = []
   for row in arcpy.da.SearchCursor(input_features, ('OBJECTID', 'SHAPE@', 'name')):
      foundMatch = False
      for row2 in uniqueList:
          if row[1].equals(row2[1]):
              foundMatch = True
              break
      if foundMatch == False
          uniqueList.append(row)
   return uniqueList
   ## no work ##
   arcpy.management.CopyFeatures(uniqueList, output_features)
Tags (2)
0 Kudos
12 Replies
JamesCrandall
MVP Frequent Contributor
Perhaps SelectLayerByAttribute to get your selection, then CopyFeatures is a better alternative?

http://resources.arcgis.com/en/help/main/10.1/index.html#//001700000071000000
0 Kudos
ArielleSimmons
New Contributor
Perhaps SelectLayerByAttribute to get your selection, then CopyFeatures is a better alternative?

http://resources.arcgis.com/en/help/main/10.1/index.html#//001700000071000000


Unfortunately the 'ARE_IDENTICAL_TO' in Select wasn't picking up any of my duplicate geometries in my test set...(go, fig. Maybe floating point error? They are lines). I tested in both GUI and code. This was the only way to grab them...
0 Kudos
MathewCoyle
Frequent Contributor
Nothing after your return is run. Return basically ends the function.
0 Kudos
JamesCrandall
MVP Frequent Contributor
Unfortunately the 'ARE_IDENTICAL_TO' in Select wasn't picking up any of my duplicate geometries in my test set...(go, fig. Maybe floating point error? They are lines). I tested in both GUI and code. This was the only way to grab them...


What if you apply a small buffer/distance_within in your selection process to try and eliminate the floating point issue?

Otherwise it could get a little messy beacause I think you would have to write coordinate pairs of each polyline to an array, create a new InsertCursor on the destination FeatureClass, create new polylines from the arrays and write them to the destination.  Not completely un-doable tho (see the last example):

http://resources.arcgis.com/en/help/main/10.1/index.html#//018w0000000t000000
0 Kudos
ArielleSimmons
New Contributor
Nothing after your return is run. Return basically ends the function.


You are absolutely right (and I need more coffee). My write-up was bad. 😛

CopyFeatures is still not my friend though... "raise e, RuntimeError: Object: Error in executing tool"...hm

import arcpy

def find_overlaps(input_features, output_features):
   uniqueList = []
   for row in arcpy.da.SearchCursor(input_features, ('OBJECTID', 'SHAPE@', 'name')):
      foundMatch = False
      for row2 in uniqueList:
          if row[1].equals(row2[1]):
              foundMatch = True
              break
      if foundMatch == False
          uniqueList.append(row)
   ## no work ##
   arcpy.management.CopyFeatures(uniqueList, output_features)
0 Kudos
MathewCoyle
Frequent Contributor
Yes you will need to make your features a layer of some sort before you copy them out. It will not accept a raw list of features as tuples. A better way to go about this might be to use an insert cursor.
0 Kudos
ArielleSimmons
New Contributor
Yes you will need to make your features a layer of some sort before you copy them out. It will not accept a raw list of features as tuples. A better way to go about this might be to use an insert cursor.


Just trying to follow...you mean use an InsertCursor instead of SearchCursor?
0 Kudos
MathewCoyle
Frequent Contributor
Just trying to follow...you mean use an InsertCursor instead of SearchCursor?


No, you will need to create an empty output feature class template based on your source feature class.

Here is how I do it. You may want to use some field mapping depending on if you need to limit the fields from source to output.
template_query = '''{0} < 0'''.format(
    arcpy.AddFieldDelimiters(input_fc, arcpy.Describe(input_fc).OIDFieldName))

arcpy.TableToTable_conversion(input_fc, out_dir, output_fc, template_query)


Then for each row you want in your output, you put it directly in the output with the insert cursor.
Maybe something like this all together.
import arcpy

def find_overlaps(input_features, output_features):

    template_query = '''{0} < 0'''.format(
        arcpy.AddFieldDelimiters(input_features, arcpy.Describe(input_features).OIDFieldName))

    arcpy.FeatureClassToFeatureClass_conversion(
        input_features, out_dir, output_features, template_query)

    field_list = ('OBJECTID', 'SHAPE@', 'name')

    with arcpy.da.InsertCursor(input_features, field_list) as insert_cursor:
        uniqueList = []

        for row in arcpy.da.SearchCursor(input_features, field_list):
            for shape in uniqueList:
                if row[1].equals(shape):
                    foundMatch = True
                    break
            if not foundMatch:
                insert_cursor.insertRow(row)
                uniqueList.append(row[1])
0 Kudos
ArielleSimmons
New Contributor
Ok. I see.... Thanks!

By the way, I've never seen this type of inline comment before... '''{0} < 0''' ... what is that? Is that .. sql notation?

template_query = '''{0} < 0'''.format(
    arcpy.AddFieldDelimiters(input_fc, arcpy.Describe(input_fc).OIDFieldName))
0 Kudos