Reputation: 189
I have a list[]
which contains phrases like list = ['123Abc','234Asx','456Aio','...']
.I would like to separate numbers from letters. The recurrent model is 3 numbers followed by capital A. How can I do that? I tried many ways using list.replace
but I don't know how to set it, or whether the existence or not of a better method to use.
Upvotes: 2
Views: 2030
Reputation: 2663
Here is another way to do it to get the result you want. This is done using re.findall
and is independent of the scenario where the separating character is 'A'.
import re
test_list = ['123Abc','234Asx','456Aio']
result = [' '.join(re.findall(r'[A-Za-z]+|\d+', x)) for x in test_list]
print(result)
Output
['123 Abc', '234 Asx', '456 Aio']
Time taken to run:
3.62 µs ± 13 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
This seems to run faster than the accepted solution. From my analysis, the accepted solution runs in approximately:
5.79 µs ± 132 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Upvotes: 0
Reputation: 17322
you can use list comprehension and add a space at position 3 in each string:
[e[:3] + ' ' + e[3:] for e in my_list]
output:
['123 Abc', '234 Asx', '456 Aio', '... ']
Upvotes: 1
Reputation: 22457
To get continuous groups of items, using a function to determine to what group each item belongs, use itertools.groupby
. In your case, you (presumably) want continuous sets of digits and non-digits, so the key
is isdigit()
, applied to each of the characters in your input string.
The number of digits can be variable, the letter-part does not need to start with A
, and you actually can have any series of digits and letters in any order: groupby
will sort it out.
The result of groupby
is an iterator (so you must convert it to something definitive such as a list), in the format "key
result, group object". You can see the isdigit
fired correctly for all characters by printing out the immediate result:
from itertools import groupby
l = ['123Abc','234Asx','456Aio']
print ([(i,list(j)) for i,j in groupby (l[0], key=lambda x:x[0].isdigit())])
which is
[(True, ['1', '2', '3']), (False, ['A', 'b', 'c'])]
Converting the list(j)
back to a single string only needs a join
. You don't want to know whether you have a list of digits or not, so you can discard the boolean result and store only the strings. This
print ([''.join(j) for i,j in groupby (l[0], key=lambda x:x[0].isdigit())])
yields
['123', 'Abc']
for the first item in your list, and if your desired result is a list for every item in your current list, add an iteration around this one:
print ([[''.join(j) for i,j in groupby (item, key=lambda x:x[0].isdigit())] for item in l])
returns
[['123', 'Abc'], ['234', 'Asx'], ['456', 'Aio']]
Upvotes: 1
Reputation: 362
try this :
text = ['A'+i.split('A')[1] for i in list]
numbers = [i.split('A')[0] for i in list]
output:
['Abc', 'Asx', 'Aio']
['123', '234', '456']
Upvotes: 0
Reputation: 2321
numbers = [int(val[:3]) for val in list]
text = [val[3:] for val in list]
Upvotes: 0