Split number into groups by magnitude
Question:
given an input 34567890
I want an output: [34, 567, 890]
I can do it with some modulo math and floor division
num=34567890
output_list = []
division_tracker = num
while division_tracker > 0:
output_list.insert(0, division_tracker%1000)
division_tracker = division_tracker//1000
Is there a better way?
Answers:
This is kind of hacky, but:
>>> list(map(int, f'{34567890:,}'.split(',')))
[34, 567, 890]
f'{n:,}'
generates a string of the integer n
with commas as thousands separators, we split the resulting string at comma and cast the parts into int
.
credit goes to @fsimonjetz
if you want to use list comprehension instead of map:
[int(x) for x in f'{34567890:,}'.split(',')]
[34, 567, 890]
Using a slice approach over strings:
s = str(345678)
n = len(s)
r = n % 3 # remainder
groups = [int(s[r + 3*i:r + 3*(i+1)]) for i in range(n//3)]
if r != 0:
groups = [int(s[-r:])] + groups
print(groups)
EDIT
A regex approach: nested gropus are not allowed so the pattern is constructed explicitely, based on the amount of digits.
import re
s = '12345678235156721'
regex = ''
if (r:=len(s) % 3) != 0:
regex += '(d{{{}}})'.format(r)
regex += '(d{3})' * (len(s) // 3)
regex = r'{}'.format(regex)
grps = list(map(int, re.search(regex, s).groups()))
Output
[12, 345, 678, 235, 156, 721]
given an input 34567890
I want an output: [34, 567, 890]
I can do it with some modulo math and floor division
num=34567890
output_list = []
division_tracker = num
while division_tracker > 0:
output_list.insert(0, division_tracker%1000)
division_tracker = division_tracker//1000
Is there a better way?
This is kind of hacky, but:
>>> list(map(int, f'{34567890:,}'.split(',')))
[34, 567, 890]
f'{n:,}'
generates a string of the integer n
with commas as thousands separators, we split the resulting string at comma and cast the parts into int
.
credit goes to @fsimonjetz
if you want to use list comprehension instead of map:
[int(x) for x in f'{34567890:,}'.split(',')]
[34, 567, 890]
Using a slice approach over strings:
s = str(345678)
n = len(s)
r = n % 3 # remainder
groups = [int(s[r + 3*i:r + 3*(i+1)]) for i in range(n//3)]
if r != 0:
groups = [int(s[-r:])] + groups
print(groups)
EDIT
A regex approach: nested gropus are not allowed so the pattern is constructed explicitely, based on the amount of digits.
import re
s = '12345678235156721'
regex = ''
if (r:=len(s) % 3) != 0:
regex += '(d{{{}}})'.format(r)
regex += '(d{3})' * (len(s) // 3)
regex = r'{}'.format(regex)
grps = list(map(int, re.search(regex, s).groups()))
Output
[12, 345, 678, 235, 156, 721]