2

I am trying to iterate all fields in a feature class/shape file to check for empty values. If there are empty records in any field, I would like to print that field.

I know Python a little bit and here is my attempt.

import arcpy
from arcpy import env

env.workspace = r"C:\SOFTWARE\Python\Jun2019"
fc ="test.shp"
##
fieldlist = arcpy.ListFields(fc)
##Iterate feilds
for field in fieldlist:
           # Iterate over each feature; if it has a non-null value
           with arcpy.da.SearchCursor(fc, field) as cursor:
               for row in cursor:
                   if row[0]h=

I am stuck here.

How do I continue?

enter image description here

I want print fields TYPE,CAT,SUBTYPE etc. which are having empty values

3
  • 1
    if not row[0] should be true for empty string and None
    – BERA
    Sep 15 '20 at 17:37
  • @BERA Strangely if not row[0] does not flag None values in text fields. I'm not really sure why?
    – Aaron
    Sep 16 '20 at 4:31
  • It does for me with file geodatabase input. (Are you sure the values are None and not a string 'None'?)
    – BERA
    Sep 16 '20 at 5:53
0

Here are two approaches. I suspect the first approach is faster as it breaks out of the loop as soon as it finds a value in a search list:

Approach 1: Classic Search Cursor

import arcpy

fc = r'C:\path\to\your\geodatabase.gdb\featureclass'

# Get a list of fields
fields = [x.name for x in arcpy.ListFields(fc)]

bad_list = []

for field in fields:
    with arcpy.da.SearchCursor(shp, field) as cursor:
        for row in cursor:
            if row[0] in ["", None, " "]:
                bad_list.append(field)
                break

print bad_list

Approach 2: Query Dictionary

Here is another approach that queries a dictionary populated by a Search Cursor.

Use a list comprehension to get a list of all the fields in the featureclass

fields = [x.name for x in arcpy.ListFields(fc)] 

Use a Search Cursor to populate a dictionary with unique values (set()).

d = {field: set(x[0] for x in arcpy.da.SearchCursor(fc, field)) for field in fields}

The resulting dictionary has the following structure:

{'Field1': ['A','B','C'], 'Field2': ['A', None, 'B'], 'Field3': [1, 2, 3]}

Now query the dictionary with the following search list [None, "", " "] and populate a list with the fields that contain items in the search list:

bad_list = [a for a, b in d.items() if any(w in b for w in [None, "", " "])]

Putting it all together:

import arcpy

fc = r'C:\path\to\your\geodatabase.gdb\featureclass'

# Get a list of fields
fields = [x.name for x in arcpy.ListFields(fc)]

# Populate a dictionary where key = field and value = list of unique values
d = {field: set(x[0] for x in arcpy.da.SearchCursor(fc, field)) for field in fields}

# Query dictionary and return list of fields that contain an item in the search list
bad_list = [a for a, b in d.items() if any(w in b for w in [None, "", " "])]
1
  • Great. This works for me
    – Arb
    Sep 18 '20 at 2:12
0

You could identify all of the rows where any of those fields are empty by including a where clause in your cursor:

with arcpy.da.SearchCursor(fc, field,'"TYPE" IS NULL or "SUBTYPE" IS NULL or "CAT" IS NULL') as cursor:
    for row in cursor: #only includes rows where at least one of the three are empty

The SQL query will vary depending on the dataset type and field types (The example above is looking for null values in a FGDB feature class).

Then you will only parse the table once.

2
  • NB: The OP mentioned both feature classes and shapefiles. Shapefiles cannot include NULL values. So you would also need to check for "" (empty string) for string fields and 0 (zero) for number fields, in addition to the check for NULL. Sep 16 '20 at 0:00
  • Great. This code works for me.
    – Arb
    Sep 18 '20 at 2:04

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.