I want to make a new column in every shapefile using for loop and populate that column using a function.

#the function

def find_folder(fn, k=-2):
    return os.path.split(fn)[0].split(os.sep)[k]

I tried:

fi = path
d = defaultdict(list)
for root, dirs, files in os.walk(fi):
    for shapefile in files:
        if shapefile.endswith('.shp'):
            arcpy.AddField_management(os.path.join(root,shapefile), "field_Tmp", "LONG")
            #here fill new field with 'find_folder(shapefile)' <---- How to do this?   

Useful notes:

When the function is used, ex.


it will give always the part of path that has a code. 1873, 8383, etc

Therefore, the field_Tmp will be populated with a number like that in every iteration for every shapefile found in the loop.

For people who know pandas it would be like this:

df = geopandas.read_file(shpfile).assign(field_Tmp = find_folder(shapefile))


Finally I am using the dictionary for the merge of all the shapefiles.

for cat, lst in d.items():
        if cat.endswith('.shp'):
            pd.concat(lst,sort = True).to_file(folder/cat)
  • Comment on you EDIT: I dont know exactly what you are doing. But you already have checked it the file is ending with shape so no need to do that again. Cant you use a list? shapelist = [] then shapelist.append(os.path.join(root,shapefile) above add field line? Then merge: arcpy.Merge....(shapelist) – BERA Dec 6 '18 at 13:27
  • This causes ERROR 000468: Input shape types are not equal . I have made gis.stackexchange.com/questions/305220/… this detailed question about it. – user10680652 Dec 6 '18 at 14:44

Use Field Calculator or da.UpdateCursor to fill the column with values.

with arcpy.da.UpdateCursor(os.path.join(root,shapefile), "field_Tmp") as cursor:
    for row in cursor:
        row[0] = find_folder(shapefile)

(I have not tried the function or the rest of your code.)

  • Yes it is your function that is causing the error. – BERA Dec 6 '18 at 12:21
  • It needed the os.path.join – user10680652 Dec 6 '18 at 12:22
  • About the d[os.path.basename(shapefile)].append(os.path.join(root,shapefile)) line, where should I put it in order to work in your answer? – user10680652 Dec 6 '18 at 13:06
  • Before add field, between add field and the cursor or after the cursor. It does not matter. What are you going to use the Dictionary for? – BERA Dec 6 '18 at 13:13
  • It does matter I think, I am doing a merge of all the shapefiles later so having the new field you just made after the concatenation is important. I added the last part of code with the merge I was referring to, so you can tell me for sure where I should put that line with the dictionary. – user10680652 Dec 6 '18 at 13:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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