Changing strings into integers
Question:
I’m going crazy and I can not figure the right solution 🙁
How can I solve that problems. I have a loop and I can get diffrent types like:
empty string
10
10K
2.3K
2.34K
2M
2.2M
2.23M
I need to change them into numbers:
0
10
10000
2300
2340
2000000
2200000
2230000
Answers:
Your steps should be:
- check if string is empty
- return 0
- check if string ends in K or M
- if it does, strip that character off the end, store it for later
- multiply by appropriate factor (K = 1000 or M = 1000000)
This can be achieved with the following:
def convert(value):
if value:
# determine multiplier
multiplier = 1
if value.endswith('K'):
multiplier = 1000
value = value[0:len(value)-1] # strip multiplier character
elif value.endswith('M'):
multiplier = 1000000
value = value[0:len(value)-1] # strip multiplier character
# convert value to float, multiply, then convert the result to int
return int(float(value) * multiplier)
else:
return 0
values = [
'',
'10',
'10K',
'2.3K',
'2.34K',
'2M',
'2.2M',
'2.23M',
]
# use a list comprehension to call the function on all values
numbers = [convert(value) for value in values]
print numbers
This should return
[0, 10, 10000, 2300, 2340, 2000000, 2200000, 2230000]
A quick hack to get the floats:
In [15]: powers = {'K': 10 ** 3, 'M': 10 ** 6}
In [16]: def f(s):
...: try:
...: if s[-1] in powers.keys():
...: return float(s[:-1]) * powers[s[-1]]
...: else:
...: return float(s)
...: except:
...: return s
...:
In [17]: map(f, ['', '10', '10K', '2.3K', '2.34K', '2M', '2.2M', '2.23M'])
Out[17]: ['', 10.0, 10000.0, 2300.0, 2340.0, 2000000.0, 2200000.0, 2230000.0]
I agree with other answers, this solution will be best to solve it without Regular Expression.
But, if you still want to use regex, here is a nice way to do this using JavaScript (sorry, not familiar with Python):
var new_arr = ['','10','10K','2.3K','2.34K','2M','2.2M','2.23M'].map(function(value) {
return value.replace(/^(d*(?:.d+)?)([kgm]?)$/i, function(_, number, group) {
return !group && (number||'0') || parseFloat(number) * Math.pow(10, {'k':3,'m':6,'g':9}[group.toLowerCase()]);
});
});
If someone could translate it to Python, it would be best (and it will teach me a bit of Python well). :))
import re
def transform_value(value):
match = re.match(r'^(d*(?:.d+)?)([kgm]?)$', value, re.IGNORECASE)
if match:
number = match.group(1) or '0'
group = match.group(2).lower()
if group:
return int(float(number) * 10**{'k': 3, 'm': 6, 'g': 9}[group])
return int(number)
return 0
new_arr = [transform_value(value) for value in
['','10','10K','2.3K','2.34K','2M','2.2M','2.23M']]
print(new_arr)
output
[0, 10, 10000, 2300, 2340, 2000000, 2200000, 2230000]
I’m going crazy and I can not figure the right solution 🙁
How can I solve that problems. I have a loop and I can get diffrent types like:
empty string
10
10K
2.3K
2.34K
2M
2.2M
2.23M
I need to change them into numbers:
0
10
10000
2300
2340
2000000
2200000
2230000
Your steps should be:
- check if string is empty
- return 0
- check if string ends in K or M
- if it does, strip that character off the end, store it for later
- multiply by appropriate factor (K = 1000 or M = 1000000)
This can be achieved with the following:
def convert(value):
if value:
# determine multiplier
multiplier = 1
if value.endswith('K'):
multiplier = 1000
value = value[0:len(value)-1] # strip multiplier character
elif value.endswith('M'):
multiplier = 1000000
value = value[0:len(value)-1] # strip multiplier character
# convert value to float, multiply, then convert the result to int
return int(float(value) * multiplier)
else:
return 0
values = [
'',
'10',
'10K',
'2.3K',
'2.34K',
'2M',
'2.2M',
'2.23M',
]
# use a list comprehension to call the function on all values
numbers = [convert(value) for value in values]
print numbers
This should return
[0, 10, 10000, 2300, 2340, 2000000, 2200000, 2230000]
A quick hack to get the floats:
In [15]: powers = {'K': 10 ** 3, 'M': 10 ** 6}
In [16]: def f(s):
...: try:
...: if s[-1] in powers.keys():
...: return float(s[:-1]) * powers[s[-1]]
...: else:
...: return float(s)
...: except:
...: return s
...:
In [17]: map(f, ['', '10', '10K', '2.3K', '2.34K', '2M', '2.2M', '2.23M'])
Out[17]: ['', 10.0, 10000.0, 2300.0, 2340.0, 2000000.0, 2200000.0, 2230000.0]
I agree with other answers, this solution will be best to solve it without Regular Expression.
But, if you still want to use regex, here is a nice way to do this using JavaScript (sorry, not familiar with Python):
var new_arr = ['','10','10K','2.3K','2.34K','2M','2.2M','2.23M'].map(function(value) {
return value.replace(/^(d*(?:.d+)?)([kgm]?)$/i, function(_, number, group) {
return !group && (number||'0') || parseFloat(number) * Math.pow(10, {'k':3,'m':6,'g':9}[group.toLowerCase()]);
});
});
If someone could translate it to Python, it would be best (and it will teach me a bit of Python well). :))
import re
def transform_value(value):
match = re.match(r'^(d*(?:.d+)?)([kgm]?)$', value, re.IGNORECASE)
if match:
number = match.group(1) or '0'
group = match.group(2).lower()
if group:
return int(float(number) * 10**{'k': 3, 'm': 6, 'g': 9}[group])
return int(number)
return 0
new_arr = [transform_value(value) for value in
['','10','10K','2.3K','2.34K','2M','2.2M','2.23M']]
print(new_arr)
output
[0, 10, 10000, 2300, 2340, 2000000, 2200000, 2230000]