1

I have a bunch of feature classes that are labeled in this pattern

CL25_E6_5_4_3

CL266_E6_5_4

CL266_E6_5_4_2

CL4_E6_5

I want to make a list in ArcPy that contains all feature classes with the same number of characters after the E (ex number of characters after *E). So in this example, only feature classes called CL25_E6_5_4_3 and CL266_E6_5_4_2 would be included in the list (because they have the same number of characters after the E) which will eventually be used to union the listed feature classes together.

Is there a wildcard symbol that represents only one character (Ex: CL266_E??????? would represent 7 characters after CL266_E) or is there a way to retrieve a count of characters after a point in the name (Ex CL266_Elen()) or specify number of characters to be in the wildcard (CL266_E[0:6])?

I'm not experienced with python, but am just trying to come up with ideas.

  • 1
    Look into the regular expressions module. – Emil Brundage Jan 7 '15 at 21:05
  • I am reading up on this and post an answer if I find one. Looks promising but I am slow when it comes to scripting. – Calavin Jan 7 '15 at 21:53
3

The ListFeatureClasses method supports a wildcard, but I don't think that this is your best option. I would start with a blank list and append the feature classes that conform by length and substring:

import sys, os, arcpy

InWorkspace = sys.argv[1] # where to find the feature classes

arcpy.env.workspace = InWorkspace # important for ListFeatureClasses

ConformingFeatClasses = list() # a new empty list

for ThisFC in arcpy.ListFeatureClasses():
    IndexOfE = ThisFC.upper().find("E") # returns -1 if no 'E' found
    if IndexOfE > 0:
        # the string contains an 'E'
        # Characters after 'E'is length of string subtract the index of the first 'E'
        AfterE = len(ThisFC) - IndexOfE 
        if AfterE == 7:
            ConformingFeatClasses.append(ThisFC)

# to utilize the list...

for ThisFC in ConformingFeatClasses:
    FullPath = os.path.join(InWorkspace,ThisFC)
    # do something with FullPath

Alternately you can look at string.split('E') which returns a list of strings broken for each 'E' - I don't know if 'E' is recurring so I've not done it that way... but would work if you're sure there's only one 'E' in the string.

If there are literally thousands of feature classes you may get a performance increase using a wildcard:

import sys, os, arcpy

InWorkspace = sys.argv[1] # where to find the feature classes

arcpy.env.workspace = InWorkspace # important for ListFeatureClasses

ConformingFeatClasses = list()
StartWild = "CL266_E"

for ThisFC in arcpy.ListFeatureClasses(StartWild + "*"):
    if len(ThisFC) == 14 and ThisFC[0:len(StartWild)].upper() == StartWild:
        ConformingFeatClasses.append(ThisFC)

# to utilize the list...

for ThisFC in ConformingFeatClasses:
    FullPath = os.path.join(InWorkspace,ThisFC)
    # do something with FullPath

Note that both methods will only list the feature classes in one workspace, which is a folder for shapefiles and for file/personal geodatabases only the standalone feature classes (not in a feature dataset) will be returned. There are of course ways to get all the feature classes in a geodatabase or all the shapefiles in all subfolders but they are significantly different in their operation I would need to know which case to code for or it would get very confusing.

Counting Underscores (sort of) method:

import sys, os, arcpy

InWorkspace = sys.argv[1] # where to find the feature classes

arcpy.env.workspace = InWorkspace # important for ListFeatureClasses

ConformingFeatClasses = list() # a new empty list

for ThisFC in arcpy.ListFeatureClasses():
    ESplit = ThisFC.split("_") # split the string into substrings for each '_'
    # len(list) returns the number of elements in the list
    # effectively counting the number of underscores unless the 
    # string ends with an underscore
    if len(ESplit) == 5: 
        ConformingFeatClasses.append(ThisFC)

# to utilize the list...

for ThisFC in ConformingFeatClasses:
    FullPath = os.path.join(InWorkspace,ThisFC)
    # do something with FullPath

The strings may be of different lengths in this case but still matching the pattern.

  • Thanks for the thoughtful answer. As I commented to radouxju's answer, the first half of the name can change number of characters as the number in the first half can change, which is why I am trying to find a way to group the feature classes with the same number of characters at the end, but not necessarily the beginning. – Calavin Jan 7 '15 at 22:09
  • The last edit counts the elements in the string separated by underscores, this I think could give the best solution. – Michael Stimson Jan 7 '15 at 22:17
1

you can also use the lenght of your names with list comprehension

newlist = [name for name in firstlist if len(name)==12 ]

or

newlist = [name for name in firstlist if len(name.split("_"))==5 ]
  • That sounds good, but I forgot to mention that the number in the first half of the name can change lengths which is why I need to find the number of characters in the second half. I will edit my question to represent this. – Calavin Jan 7 '15 at 21:48
  • That doesn't sound too difficult. If you give some examples I can modify my answer to suit. Specifically what does match and what doesn't match. Is the first part always with underscores? – Michael Stimson Jan 7 '15 at 21:57
  • The first part will always be CLx_E6 Where x is a number with 1 to 3 digits (ex CL1_E6, CL12_E6, CL123_E6). The rest will follow a pattern of _#_#_#. I need lists of feature classes with the same frequency of _#. Hope that clears it up. – Calavin Jan 7 '15 at 22:02
  • 1
    would it help to just count the underscores? – Michael Stimson Jan 7 '15 at 22:09

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.