I created two dictionaries, dictionaryone and dictionarytwo, and both contain the same key. The key is a file path to a shapefile, for example: C:\TestFolder\Folder1\A\address_pt.shp. In addition, dictionaryone has a value that is a list of field names contained within the attribute table of the shapefile.

Below is an example of dictionaryone output:

{'C:\\TestFolder\\Folder1\\A\\address_pt.shp': ['FID', 'Shape', 'FULL_ADDRE', 'STREET_ADD', 'CITY_ST_ZI', 'PREFIX_DIR', 'HALF_ADDRE', 'HOUSE_NUMB', 'STREET_NAM', 'STREET_TYP', 'SUFFIX_DIR', 'UNIT_TYPE', 'UNIT_ID', 'CITY', 'STATE', 'ZIPCODE', 'PARCEL_NUM', 'PARCEL_N_1', 'HOUSE_NU_1', 'HOUSE_NU_2', 'STATUS', 'Assembly_S', 'Senate', 'District', 'Council', 'GRIDNUM', 'PHYSICAL_A', 'PUBDATE']}

Furthermore, dictionarytwo contains a list of field names that are thought to be within the shapefile. Below is an example of dictionarytwo. Notice that both dictionaries have the same key.

{'C:\\TestFolder\\Folder1\\A\\address_pt.shp': ['house_numb', 'half_addre', 'prefix_dir', 'street_nam', 'street_typ', 'suffix_dir', 'unit_type', 'unit_id', 'street_add', 'city', 'state', 'zipcode']}

My goal is to use the list of field names in dictionarytwo and search through dictionaryone to see if field names from dictionary two exist in dictionaryone. I assume that I have to standardize the strings in both dictionary lists in order to search and if that assumption is true, I would like to capitalize the lists in both dictionaries before searching.

In addition, I would like to capture the results of the search and input the results into two new empty fields. The first field would be named something like field_found and include the matching fields found in both dictionaries. The second field would be named something like fields_not_found and include the fields from dictionarytwo that are not found in dictionaryone.

I'm not sure if this process is possible and I can't figure out the code logic. I'm not sure if using dictionaries is the best approach. Below is the code that I currently have and it creates both dictionaries.

import arcpy

arcpy.env.workspace = r"C:\TestFolder"
dbf = "ProcessControlTable"
dbf1 = "APExistOnlyEdit.dbf"
myfield = "FI_PATH"

filepathlist2 =[row[0] for row in arcpy.da.SearchCursor(dbf1,myfield)]

#Dictionary holding Field Names that are within Shapefile
dictionaryone = {}

for thisFile in filepathlist2:
    ContainedFieldNames = [f.name for f in arcpy.ListFields(thisFile)]
    dictionaryone[thisFile] = ContainedFieldNames


##Not sure how to insert field list into dictionary two for searching
##         'AP_FULLADD','AP_CITY','AP_STATE','AP_ZIP')

#Dictionary holding Field Names that are thought to exist in Shapefile
dictionarytwo = {}

    for row in rows:    
        dictionarytwo[row[0]] = [a for a in row[1:] if a.strip() != '']

  • 1
    This is not really a GIS issue, it's a coding issue best asked on Stack Overflow. A simply loop asking if a value is in a list will suffice and to capitalize your text suggest you review the various string functions here.
    – Hornbydd
    Jan 24 '20 at 15:41

Easier than casting your data into dictionaries would be to use the native list fields function in arcpy to get list of your field names. Then put those lists into sets and do the difference and intersection of those lists.

import arcpy

inFC1 = r"C:\gTemp\deleteme.shp"
inFC2 = r"C:\gTemp\kblirestricedareas.shp"

#Get the field names as lists...
fields1 = [f.name for f in arcpy.ListFields(inFC1)]
fields2 = [f.name for f in arcpy.ListFields(inFC2)]

#Put the lists into sets and do the difference...
differentFields = set(fields1) - set(fields2)
print (differentFields)

#Put the lists into sets and do the intersection....
sameFields = set(fields1) & set(fields2)
print (sameFields)

Iterate through your first dictionary and pull out the key and the list of fields. Pull out your second list of fields using the same key. create an uppercase list of your second fields. Iterate through your first list of fields. After capitalization check if it's in the uppercase second list. You can create two lists this way; one of found one of not found.

#dictionary 1
d1 = {'C:\\TestFolder\\Folder1\\A\\address_pt.shp': ['FID', 'Shape', 'FULL_ADDRE', 'STREET_ADD', 'CITY_ST_ZI', 'PREFIX_DIR', 'HALF_ADDRE', 'HOUSE_NUMB', 'STREET_NAM', 'STREET_TYP', 'SUFFIX_DIR', 'UNIT_TYPE', 'UNIT_ID', 'CITY', 'STATE', 'ZIPCODE', 'PARCEL_NUM', 'PARCEL_N_1', 'HOUSE_NU_1', 'HOUSE_NU_2', 'STATUS', 'Assembly_S', 'Senate', 'District', 'Council', 'GRIDNUM', 'PHYSICAL_A', 'PUBDATE']}
#dictionary 2
d2 = {'C:\\TestFolder\\Folder1\\A\\address_pt.shp': ['house_numb', 'half_addre', 'prefix_dir', 'street_nam', 'street_typ', 'suffix_dir', 'unit_type', 'unit_id', 'street_add', 'city', 'state', 'zipcode']}

#iterate dictionary 1
for shp, flds1 in d1.items ():
    ##get fields from dictionary 2
    flds2 = d2 [shp]

    #create uppercase field list
    #list comprehension works but this will be easier to understand
    flds2Upper = []
    for fld in flds2:
        flds2Upper += [fld.upper ()]

    #found and not found lists
    found = []
    notFound = []

    #iterate first list of fields
    for fld in flds1:
        fldUpper = fld.upper ()
        #field exists in uppercase fields 2?
        if fldUpper in flds2Upper:
            #add to found
            found += [fld]
            #add to not found
            notFound += [fld]

    #show results
    print "shp: {}".format (shp)
    print "{} fields found:".format (len (found))
    for fld in found:
        print fld
    print "{} fields not found:".format (len (notFound))
    for fld in notFound:
        print fld

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