Hello, I am pretty new with using python in Pro. I need to modify feature class output names as they are being generated, or after they are created.
I have a list of features in a feature dataset (since this is a list, I am assuming using listFeatureClass, for loop, and f strings is how I cycle through the layers)
EX_feature1
EX_feature2
EX_feature3
I want to remove the "EX_" from the feature class name and add "TR" in its place.
Is this a strip function? can that be applied to fc names? Thanks in advance!
Solved! Go to Solution.
replace should work
fcs = ["c:/path/EX_feature1","c:/path/EX_feature2", "c:/path/EX_feature3"]
out_fcs = [i.replace("EX_", "TR") for i in fcs]
out_fcs
['c:/path/TRfeature1', 'c:/path/TRfeature2', 'c:/path/TRfeature3']
If you know you just need to replace the first 3 characters (say it was a state code with an underscore or something) you could also do:
out_fcs = [f"TR{fc[3:]}" for fc in fcs]
Using replace can sometimes burn you since by default it replaces *all* matching substrings unless you specify a limit. Meaning "aaabbbaaa".replace("a", "b") will give you "bbbbbbbbb" or "tr_tracks".replace("tr", "ex") would give you "ex_exacks"
replace should work
fcs = ["c:/path/EX_feature1","c:/path/EX_feature2", "c:/path/EX_feature3"]
out_fcs = [i.replace("EX_", "TR") for i in fcs]
out_fcs
['c:/path/TRfeature1', 'c:/path/TRfeature2', 'c:/path/TRfeature3']
If you know you just need to replace the first 3 characters (say it was a state code with an underscore or something) you could also do:
out_fcs = [f"TR{fc[3:]}" for fc in fcs]
Using replace can sometimes burn you since by default it replaces *all* matching substrings unless you specify a limit. Meaning "aaabbbaaa".replace("a", "b") will give you "bbbbbbbbb" or "tr_tracks".replace("tr", "ex") would give you "ex_exacks"
Thank you! Is your example setting the output variable? So I am clipping several layers and then renaming them to exclude the first 3 characters and replace with a different amount of characters, would that still work?
ex. "EX_" gets removed and I add in "TR100yr_". so then my version of your line looks like outFeature = [f"TR100yr_{fc[3:]}" for fc in fcs]. Is the "3" just the number of characters to replace or an index?
It is! In Python, strings implement the Sequence protocol, so you can iterate them and slice them like lists. The [3:] syntax is a slice that starts after the 3rd element and runs to the end. you can also truncate the last 3 with [3:-3] or get every other character between the first and last 3 with [3:-3:2]
>>> text = "abc_hello-world"
>>> text[3:]
... '_hello-world'
>>> text[3:-3]
... '_hello-wo'
>>> text[3:-3:2]
... '_el-o'
@HaydenWelch That seemed to do the trick for my use case, thank you!
@SeanLukacs,
If you need a bit more robustness on future data sets you could look at regex substitution (re.sub()). re.sub() will gracefully handle start matches, multiple matches, and non-matches with about the same amount of code. Here's an example:
import re
fcs = [
"EX_feature1",
"EX_feature2",
"feature4",
"EX_feature5_EX_",
]
print(f"Original: {fcs}")
print(f'string replace: {[i.replace("EX_", "TR_") for i in fcs]}')
print(f'string slicer: {[f"TR_{fc[3:]}" for fc in fcs]}')
print(f"regex substitution: {[re.sub(r'^EX_', 'TR_', fc) for fc in fcs]}")
Output:
Original: ['EX_feature1', 'EX_feature2', 'feature4', 'EX_feature5_EX_']
string replace: ['TR_feature1', 'TR_feature2', 'feature4', 'TR_feature5_TR_']
string slicer: ['TR_feature1', 'TR_feature2', 'TR_ture4', 'TR_feature5_EX_']
regex substitution: ['TR_feature1', 'TR_feature2', 'feature4', 'TR_feature5_EX_']
<Note: I changed from required 'TR' to 'TR_' for readability in this example only.>
HTH,
Tyler
@TylerT Thanks for that!
@SeanLukacs ,
I noticed in the Python docs that `string.replace()` has an optional count keyword giving it a bit more flexibility. If keyword count is passed, only the first count occurrences are replaced. This might be useful for your case also.
Tyler