How to access Field Names

2860
12
Jump to solution
08-04-2017 08:52 AM
VishalShah2
Occasional Contributor II

So I am working on a custom tool that uses one of the existing fields to make a selection by attribute. For example, say I have a feature called Target Feature and in the feature, the fields were called Field1, Field2, Field3, and Field4. I am trying to get a variable to be set equal to arcpy.ListFields('Target Feature') and then to check if a field name is in that feature. The selection I want wasn't working, no selection was being made actually. Here's what I was leaning towards but it didn't work for me:

import arcpy

fieldList = arcpy.ListFields('Target Feature')
fieldName = ['Field3']
fieldValue = ['%45B%']

if fieldName in fieldList:
    if fieldValue in fieldName:
        arcpy.SelectLayerByAttribute_management ('Target Feature', NEW_SELECION, "Field3 LIKE " + "'" + str(fieldValue) + "'")‍‍‍‍‍‍‍‍‍

But this isn't working for me. Any help is appreciated!

0 Kudos
1 Solution

Accepted Solutions
ClintonDow1
Occasional Contributor II

Hello Vishal, 

There are some issues with your if statements, so currently the script will never make it to the SelectLayerByAttribute call. 

The first conditional is:

fieldList = arcpy.ListFields('Target Feature')
fieldName = ['Field3']
fieldValue = ['%45B%']

if fieldName in fieldList:‍‍‍‍‍‍‍‍‍‍

fieldName is a list, since you surrounded it with square brackets. So you are checking if a list holding 'Field3' is in fieldList, not the 'Field3' string itself. The result of arcpy.ListFields contains Field objects which possess a name Property - so we can use a list comprehension to extract them. The result will look something like: ['Field1', 'Field2', 'Field3'], so we can see ['Field3'] isn't inside, however 'Field3' by itself is. This post explains how to search for a list of values within another list, and may help clear it up further.

The second conditional:

    if fieldValue in fieldName:‍‍‍‍‍‍‍‍

Has a similar issue - The list ['%45B%'] does not exist inside ['Field3'], which again has no sublists. At this point, instead you may want to check the value of each row inside 'Target Feature', this is where Cursors come in. However, for what you are trying to do in this script, Cursors are unnecessary, I just wanted to mention them for your benefit.

You don't need to use cursors, because the arcpy.SelectLayerByAttribute_management() tool allows you to provide a query, which you are doing in your above example. This loops through the feature class automatically, cursors loop through it manually.

So therefore, we just need a single conditional statement in this case. With these changes, this should be the result:

import arcpy

fieldList = arcpy.ListFields('Target Feature')
fieldName = 'Field3'
fieldValue = '%45B%'

# list comp to extract field names
if fieldName in [f.name for f in fieldList]:
   query = "Field3 LIKE " + "'" + str(fieldValue) + "'"
   arcpy.SelectLayerByAttribute_management ('Target Feature', NEW_SELECION, query)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Its also worth mentioning, in case you run into it, that in some cases 'Target Feature' won't be enough and you may need the full path to the dataset on disk. 

(Shoutout to vangelo-esristaff‌ for a reminder on the Field objects )

View solution in original post

12 Replies
JoshuaBixby
MVP Esteemed Contributor

Can you elaborate on "isn't working for me?"  Are you getting errors or unexpected results?  If errors, what errors exactly (paste the error message here)?  If unexpected results, what are you getting and what do you expect?

VishalShah2
Occasional Contributor II

Sorry about that Joshua, my issue was that the selection wasn't being made. Was bogged down by other projects I forgot to mention what wasn't working.

0 Kudos
VinceAngelo
Esri Esteemed Contributor

Always be careful to understand what an ArcPy function returns. ListFields returns a list of Field objects, which while they include name, also includes type, isNullable, length and a number of other properties. You'd need to use a list comprehension to map the array of Fields to an array of names.

- V

ClintonDow1
Occasional Contributor II

Hello Vishal, 

There are some issues with your if statements, so currently the script will never make it to the SelectLayerByAttribute call. 

The first conditional is:

fieldList = arcpy.ListFields('Target Feature')
fieldName = ['Field3']
fieldValue = ['%45B%']

if fieldName in fieldList:‍‍‍‍‍‍‍‍‍‍

fieldName is a list, since you surrounded it with square brackets. So you are checking if a list holding 'Field3' is in fieldList, not the 'Field3' string itself. The result of arcpy.ListFields contains Field objects which possess a name Property - so we can use a list comprehension to extract them. The result will look something like: ['Field1', 'Field2', 'Field3'], so we can see ['Field3'] isn't inside, however 'Field3' by itself is. This post explains how to search for a list of values within another list, and may help clear it up further.

The second conditional:

    if fieldValue in fieldName:‍‍‍‍‍‍‍‍

Has a similar issue - The list ['%45B%'] does not exist inside ['Field3'], which again has no sublists. At this point, instead you may want to check the value of each row inside 'Target Feature', this is where Cursors come in. However, for what you are trying to do in this script, Cursors are unnecessary, I just wanted to mention them for your benefit.

You don't need to use cursors, because the arcpy.SelectLayerByAttribute_management() tool allows you to provide a query, which you are doing in your above example. This loops through the feature class automatically, cursors loop through it manually.

So therefore, we just need a single conditional statement in this case. With these changes, this should be the result:

import arcpy

fieldList = arcpy.ListFields('Target Feature')
fieldName = 'Field3'
fieldValue = '%45B%'

# list comp to extract field names
if fieldName in [f.name for f in fieldList]:
   query = "Field3 LIKE " + "'" + str(fieldValue) + "'"
   arcpy.SelectLayerByAttribute_management ('Target Feature', NEW_SELECION, query)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Its also worth mentioning, in case you run into it, that in some cases 'Target Feature' won't be enough and you may need the full path to the dataset on disk. 

(Shoutout to vangelo-esristaff‌ for a reminder on the Field objects )

RandyBurton
MVP Regular Contributor

So if the field name is edited in line 4, how about this for line 9:

query = fieldName + " LIKE '" + str(fieldValue) + "'"
ClintonDow1
Occasional Contributor II

Yes good point, that will work and makes it more robust. 

VishalShah2
Occasional Contributor II

Clinton,

What if fieldValue had more than one input? Say:

fieldValue = '%45B%', '%46A%', '%47C%'

Would that still work the way you have the script written?

0 Kudos
ClintonDow1
Occasional Contributor II

In that case it would be appropriate to surround the three values in square brackets to create a list, because you have multiple strings and want to compare for each one of them.

fieldValues = ['%45B%', '%46A%', '%47C%']‍‍

Then you can use the SQL IN operator instead of LIKE in that case. The syntax would be:

query = "Field3 IN" + "(" + ', '.join(fieldValues) + ")"# "Field3 IN (‍‍'%45B%', '%46A%', '%47C%')‍‍‍‍
VishalShah2
Occasional Contributor II

But I'd want to check to see if the list that is set to fieldValues is in Field3. So wouldn't it be the other way around from how you have the join listed?

0 Kudos