Reputation: 21
I am trying to manipulate a file name to remove an underscore.
final_name = '{0}{1}{2}_{4}_new'.format(*filename.split('_'))
The filename is something like - 2024_10_10_091530_xyz_new.txt
and the code does work fine and I can get the desired result 20241010_xyz_new
as the final name.
How would I be able to get the same result using an f-string?
Upvotes: 0
Views: 87
Reputation: 155584
Generally you would two-line it, one to split and unpack, one to use the unpacked names:
# Limit to 5 splits to avoid oversplitting when suffix name has additional
# underscores you don't care about
year, month, day, _, name, _ = filename.split('_', 5)
final_name = f'{year}{month}{day}_{name}_new'
The first line just splits it up and unpacks the result (ignoring the two components of the original name we don't care about, but still listing them to ensure they actually exist as expected). Additional underscores are allowed to exist in the ignored suffix, we avoid them causing unpacking exceptions (and speed up the split very slightly by avoiding unnecessary work looking for them) by explicitly limiting to no more than five splits.
After that, we have access to all of them as named variables (making the intent of the code rather more obvious) and can use those names in the f-string placeholders.
Note that this code is rather brittle as written. We claim it's getting year
, month
, day
, etc., but all we really checked is the underscore count is at least five (if it was less than five, the unpacking would die with an exception). This is a case where a more rigorous check via a regex might help you, e.g.:
import re # At top of file
# Adjust regex to be more or less permissive as appropriate, e.g.
# allowing fewer digits in date components if that's expected,
# allowing wider ranger of characters in "name" component, etc.
if m := re.fullmatch(r'(\d{4})_(\d{2})_(\d{2})_\d{6}_([a-z]+)_new.txt', filename):
year, month, day, name = m.groups()
final_name = f'{year}{month}{day}_{name}_new'
else:
# Not in expected form handle error here
Upvotes: 3
Reputation: 120738
Use the walrus:
>>> filename = '2024_10_10_091530_xyz_new.txt'
>>> f'{(a:=filename.split('_'))[0]}{a[1]}{a[2]}_{a[4]}_{a[5]}'
'20241010_xyz_new.txt'
Upvotes: 0
Reputation: 12822
Assuming the date part has constant width
fn = '2024_10_10_091530_xyz_new.txt'
print(f"{fn[0:4]}{fn[5:7]}{fn[8:10]}{fn[17:]}")
Result
20241010_xyz_new.txt
Also this convoluted one
print(f"{''.join([c for i,c in enumerate(fn[:]) if i not in [4,7,10] and (i < 11 or i > 16)])}")
Upvotes: 0
Reputation: 2149
Like this:
filename = "2024_10_10_091530_xyz_new.txt"
parts = filename.split('_')
final_name = f"{''.join(parts[:3])}_{parts[4]}_new"
print(final_name)
# Output: 20241010_xyz_new
Upvotes: 0