I've got a problem with the following script:
import arcpy, os
infile = r"C:\temp4\ALK_Merge.shp"
infileL = "infile_Layer"
count = int(arcpy.GetCount_management(infile).getOutput(0))
x = 99
xC = count/x
xC1 = xC + 2
for i in range(1, xC1):
print i
sPath = infile.split(".shp")
print sPath
xRange = i * 99
xRange1 = (i*99)-99
print xRange
print xRange1
outFeature = sPath + "_" + i + ".shp"
arcpy.MakeFeatureLayer_management (infile, infileL)
arcpy.SelectLayerByAttribute_management (infileL, "NEW_SELECTION", "\"FID\" <= " + xRange + "AND" + "\"FID\" >= "+ xRange1 + "")
arcpy.CopyFeatures_management(infileL, outFeature)
The problem is in line 25:
outFeature = sPath + "_" + i + ".shp"
TypeError: can only concatenate list (not "str") to list
Any ideas how to solve this?
Solved! Go to Solution.
The method you are using to create the chunks to get exactly 99 features will only work in case there were no deletes in the featureclass.
Take the following example:
def main():
import arcpy
fc = r'C:\GeoNet\ArcadeMedellin\ArcadeMedellin.gdb\Solicitudes'
oids = [r[0] for r in arcpy.da.SearchCursor(fc, ('OID@'))]
print "FID 99 is at index:", oids.index(99)
cnt = 0
for lst in chunks(oids, 99):
cnt += 1
print "\nChunk {0} has {1} elements".format(cnt, len(lst))
print " - OID from {0} to {1}".format(min(lst), max(lst))
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in range(0, len(l), n):
yield l[i:i + n]
if __name__ == '__main__':
main()
this will yield:
FID 99 is at index: 92
Chunk 1 has 99 elements
- OID from 1 to 105
Chunk 2 has 99 elements
- OID from 106 to 211
Chunk 3 has 36 elements
- OID from 212 to 250
The OID are not continuous, so the chunk function provides a more stable way of creating the appropriate chucks of 99 elements.
When yo do sPath = infile.split(".shp") on line 16 he variable sPath will be a list and can't be concatenated with a string. However there are more things going on in your code. I will post an alternative later.
Because I want to tile the "bigger" shape into "shapes" with exactly 99 features and therefore need to give different names for the output feature class.
try this:
def main():
import arcpy
import os
arcpy.env.overwriteOutput = True
infile = r"C:\temp4\ALK_Merge.shp"
infileL = "infile_Layer"
count = int(arcpy.GetCount_management(infile).getOutput(0))
x = 99
xC = count/x
xC1 = xC + 2
for i in range(1, xC1):
print i
# this will cut off the extension .shp
fc_pathname = os.path.splitext(infile)[0]
xRange = i * 99
xRange1 = (i*99)-99
print xRange
print xRange1
# this will create the file path to the output shapefile
fc_pathname = "{0}_{1}.shp".format(fc_pathname, i)
arcpy.MakeFeatureLayer_management (infile, infileL)
# this will define the where clause
where = "FID >= {0} AND FID <= {1}".format(xRange1, xRange)
arcpy.SelectLayerByAttribute_management (infileL, "NEW_SELECTION", where)
arcpy.CopyFeatures_management(infileL, outFeature)
if __name__ == '__main__':
main()
The method you are using to create the chunks to get exactly 99 features will only work in case there were no deletes in the featureclass.
Take the following example:
def main():
import arcpy
fc = r'C:\GeoNet\ArcadeMedellin\ArcadeMedellin.gdb\Solicitudes'
oids = [r[0] for r in arcpy.da.SearchCursor(fc, ('OID@'))]
print "FID 99 is at index:", oids.index(99)
cnt = 0
for lst in chunks(oids, 99):
cnt += 1
print "\nChunk {0} has {1} elements".format(cnt, len(lst))
print " - OID from {0} to {1}".format(min(lst), max(lst))
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in range(0, len(l), n):
yield l[i:i + n]
if __name__ == '__main__':
main()
this will yield:
FID 99 is at index: 92
Chunk 1 has 99 elements
- OID from 1 to 105
Chunk 2 has 99 elements
- OID from 106 to 211
Chunk 3 has 36 elements
- OID from 212 to 250
The OID are not continuous, so the chunk function provides a more stable way of creating the appropriate chucks of 99 elements.
Not that it will perform any better, I haven't tested, but native slicing and itertools.izip_longest can also be used:
import arcpy
from itertools import izip_longest
chunk_size = #
fc = #
chunk_start = slice(0, None, chunk_size)
chunk_end = slice(chunk_size - 1, None, chunk_size)
with arcpy.da.SearchCursor(fc, "OID@") as cur:
oids = [oid for oid, in cur]
oid_chunks = izip_longest(oids[chunk_start],
oids[chunk_end],
fillvalue=oids[-1])
list(oid_chunks)
Perfect thank you !
Only a very small thing - it's not
arcpy.CopyFeatures_management(infileL, outFeature) must be:
arcpy.CopyFeatures_management(infileL,
fc_pathname
) I think?
Very true. Good catch!
Isn't the value of i numeric as well? That seems problematic as well. While solidly in the rookie phase in my Python carreer, could you join spath into a string, and then concatenate it with i after casting i as a string:
spath = ''.join(infile.split(".shp"))
outfeature = spath+'_'+str(i)+'_ '".shp"
Untested: 6:00 am at the kitchen table with only one cup of coffee on board....
eta... Never mind: Looks like Xander slipped in his repsonse while I hacking....