1

So far I have a code which iterates through Fefature Classes and ignores all fields of type String, Geometry and OID.

I now try to add some lines which tell python to ignore all NULL values when looping through an integer/float/double field. I work with ArcGIS 10.1 Any ideas how to do so? I believe it must be with SearchCursor but I do not know how.

for FCLASS in FCs:

#Skip all Text. OID and Geometry Fields - unfortunately WID, Shape Area etv is still included
AllFields = [f.name for f in arcpy.ListFields(FCLASS)]
LeaveOutField = [f.name for f in arcpy.ListFields(FCLASS,field_type='String')]
LeaveOutField.extend([f.name for f in arcpy.ListFields(FCLASS,field_type='Geometry')])
LeaveOutField.extend([f.name for f in arcpy.ListFields(FCLASS,field_type='OID')])
attrlist = [x for x in AllFields if x not in LeaveOutField]

# text element that has to change (e.g. title...)
title = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "map_title")[0]
for attr in attrlist:
    rows = arcpy.SearchCursor(attr, "row IS NOT NULL")
    for row in rows:
         if attr["*"] is not None:
             #Do Stuff here
3
  • 1
    It's the value of the field that contains NULL not the field itself... you need to skip these inside the cursor like if row[n] != None: (equivalent to not IsDBNull(row[n]) in arcobjects). If you want to skip the rows that do contain null values then use the whereclause "ExampleField is not NULL"... does that explain it? Jun 23, 2015 at 5:03
  • I edited my code with how I think you mean it, it gives me an IOError.. Jun 23, 2015 at 7:31
  • 1
    Let me rephrase what @MichaelMiles-Stimson said, in cursors the main processing unit is the rows or records. More clearly, by a cursor, you can iterate through rows (not columns/fields) while collecting values from the desired fields. There are a few issues in your code as well. 1.There are more efficient ways of listing desired fields, 2.To be able to get a result from your "row IS NOT NULL" SQL statement, you should have a field named "row", which I do not think the case, 3.attrlist is a list and attr is an element from that (a string of course), therefore attr["*"] will throw an exception.
    – fatih_dur
    Jun 23, 2015 at 11:41

2 Answers 2

2

The NULL values are in the table, not in the fields, the check for NULL occurs in the loop or when you create the cursor using a whereclause:

for FCLASS in FCs:

    #Skip all Text. OID and Geometry Fields - unfortunately WID, Shape Area etv is still included
    AllFields = [f.name for f in arcpy.ListFields(FCLASS)]
    LeaveOutField = [f.name for f in arcpy.ListFields(FCLASS,field_type='String')]
    LeaveOutField.extend([f.name for f in arcpy.ListFields(FCLASS,field_type='Geometry')])
    LeaveOutField.extend([f.name for f in arcpy.ListFields(FCLASS,field_type='OID')])
    attrlist = [x for x in AllFields if x not in LeaveOutField]

    # text element that has to change (e.g. title...)
    title = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "map_title")[0]
    dQ = ["%s is not NULL" % F for F in attrlist]
    with arcpy.da.SearchCursor(FCLASS, attrlist, ' and '.join (dQ)) as rows:
        # all of these rows do not contain NULL values
        for row in rows:
            # do your stuff here safe knowning that no null values exist

Building the definition query dynamically with the fields... let's have a look at that interactively:

>>> attrlist = ['one','two','three']
>>> dQ = ["%s is not NULL" % F for F in attrlist]
>>> print dQ
['one is not NULL', 'two is not NULL', 'three is not NULL']
>>> print ' and '.join (dQ)
one is not NULL and two is not NULL and three is not NULL

Or while you're iterating the row:

for FCLASS in FCs:

    #Skip all Text. OID and Geometry Fields - unfortunately WID, Shape Area etv is still included
    AllFields = [f.name for f in arcpy.ListFields(FCLASS)]
    LeaveOutField = [f.name for f in arcpy.ListFields(FCLASS,field_type='String')]
    LeaveOutField.extend([f.name for f in arcpy.ListFields(FCLASS,field_type='Geometry')])
    LeaveOutField.extend([f.name for f in arcpy.ListFields(FCLASS,field_type='OID')])
    attrlist = [x for x in AllFields if x not in LeaveOutField]

    with arcpy.da.SearchCursor(FCLASS, attrlist) as rows:
        chkRange = range(len(attrlist))
        for row in rows:
            ContainsNull = False
            for Index in chkRange:
                if row[Index] == None:
                    ContainsNull = True
                    break
            if not ContainsNull:
                # this row doesn't contain any null values
2

In you're code you're using a field name as the dataset parameter in your search cursor. Search cursors are a means of accessing data from a table.

Try instead:

rows = arcpy.SearchCursor(FCLASS)
for row in rows:
    #Get field value
    value = row.getValue (attr)
    #Check if value is null
    if value == None:
        #skip row
        continue
    #Do Stuff here
2
  • The code works.. but can you explain me why it skips the Null values? Because as I understand it if value == None: continue should only take rows with a Null value, what am I missing here? Jun 24, 2015 at 4:01
  • You might be a bit confused about what continue does in Python. It doesn't mean continue to the next line, but instead continue the next iteration of the loop it occurs within. Jun 24, 2015 at 4:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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