I have file names like this: 13_CL 13_CR 13_TL 13_TR ... and I assigned them to a variable. I need to switch numbers and alphabetical characters in the filenames. the expected result is: CL_13 CR_13 TL_13 TR_13 ...
Asked
Active
Viewed 110 times
0
-
For each name, `switched_name = '_'.join(reversed(name.split('_')))` – Shinra tensei Aug 10 '21 at 10:07
5 Answers
2
You might split the value on _
then reverse the array and join back with a _
s="13_CL"
print('_'.join(s.split('_')[::-1]))
Output
CL_13
A regex solution to switch numbers and alphabetical characters could be to capture 1+ digits in group 1 and 1+ chars A-Z in group 2 and in the replacement use the groups in the reversed order.
import re
s="13_CL"
print(re.sub(r"(\d+)_([A-Z]+)", r"\2_\1", s))
Output
CL_13

The fourth bird
- 154,723
- 16
- 55
- 70
2
There are a lots of possibilities here.
One is :
filename_list = ['13_CL', '13_CR', '13_TL', '13_TR']
new_filename_list = ['_'.join(reversed(filename.split('_'))) for filename in filename_list]
split
split the string into a list on delimiter
reversed
is used to reverse the list order. It produces an iterator which is consumed directly by join
without the need to really create a full list object.
join
to create a new string from a iterable using a delimiter

Cyrille Pontvieux
- 2,356
- 1
- 21
- 29
-
@shinra_tensei also proposes to use `revesed` function instead of `[::-1]` construction which I think is better (because it creates a iterator) – Cyrille Pontvieux Aug 10 '21 at 10:11
-
-
-
I edited my post and also added an explanation why an iterator is a better idea in this case – Cyrille Pontvieux Aug 10 '21 at 10:19
-
So you're not familiar with [this](https://stackoverflow.com/a/9061024/12671057) or is it not true anymore? – Kelly Bundy Aug 10 '21 at 10:22
-
It’s still true and this is why creating a list for join is not as good as creating an iterator or generator for it. – Cyrille Pontvieux Aug 10 '21 at 10:23
-
-
No it isn’t, it says creating a list-comprehension is worse than creating a list directly. But this is worse than just creating a iterator. – Cyrille Pontvieux Aug 10 '21 at 10:27
-
-
Ok my bad, yes for the CPython implementation of `str.join` it’s a bit faster to have a list because the implementation seems to need to read the data twice. Nevertheless it’s better to use Iterators in general cases, even if in that special case (using CPython) you don’t get faster run. It’s an implementation detail that is subject to change. So for the OP learning curve, I still think it’s better to user iterators whenever it’s possible. Feel free to contradict me. – Cyrille Pontvieux Aug 10 '21 at 10:34
-
Maybe, but *"consumed directly by join without the need to really create a full list object"* is still misleading. – Kelly Bundy Aug 10 '21 at 10:40
1
We could use a regex approach here:
filenames = ['13_CL', '13_CR', '13_TL', '13_TR']
output = [re.sub(r'(.*)_(.*)', r'\2_\1', x) for x in filenames]
print(output) # ['CL_13', 'CR_13', 'TL_13', 'TR_13']

Tim Biegeleisen
- 502,043
- 27
- 286
- 360
-
Also good other option ;-) for `OP`, `re` is a module to import. – Cyrille Pontvieux Aug 10 '21 at 10:22
0
Here is a one line version:
s = ' '.join(['_'.join(reversed(pair.split('_'))) for pair in s.split(' ')])

James Bear
- 434
- 2
- 4
0
Try this
str1='13_CL 13_CR 13_TL 13_TR'
str2=' '.join('_'.join(reversed(a.split('_'))) for a in str1.split())
print(str2)