views:

147

answers:

4

I have variables with values like 1.7m 1.8k and 1.2b how can I convert them to a real number value for example

1.7m = 1700000
1.8k = 1800
1.2b = 1200000000
+9  A: 

I would define a dictionary:

tens = dict(k=10e3, m=10e6, b=10e9)

then

x='1.7m'
factor, exp = x[0:-1], x[-1].lower()
ans = int(float(factor) * tens[exp])
Vicki Laidler
+1: Allows someone to split the hair of `m` meaning 1e6 or 1024*1024.
S.Lott
The dictionary approach is problematic due to where I intend to implement this. but thanks. I'll update what I went with in a little bit
Pevo
"problematic"? That's meaningless. Could you explain why a simple solution won't work?
S.Lott
@Pevo, The usage of a dictionary here is exactly the same as the usage in the accepted answer.
Mike Graham
+1  A: 

Here is an example using re:

input = '17k, 14.05m, 1.235b'

multipliers = { 'k': 1e3,
                'm': 1e6,
                'b': 1e9,
              }

pattern = r'([0-9.]+)([bkm])'

for number, suffix in re.findall(pattern, input):
    number = float(number)
    print number * multipliers[suffix]
Joe Koberg
muchhh thankssssss
Pevo
Or even `pattern = r'([0-9.]+)(%s)' % '|'.join(multipliers)` to avoid the minor repetition of units in there.
Will McCutchen
@Will, being that `[bkm]` will only match one character, I don't see how there could be a "minor repetition of units in there". I do like your suggestion of doing a join on multipliers, but not for the reason you stated.
tgray
He is saying you can use the already-specified dictionary keys to fill out the RE rather than retyping 'bkm'.
Joe Koberg
But i considered that less easy to understand in this simple case. If the dict had all the SI prefixes in it or somesuch, I would definitely have done that.
Joe Koberg
Using regex here is quite unnecessary.
Mike Graham
Mike: Please feel free to provide a simpler or more effective answer.
Joe Koberg
@Joe, Vicki Laidler's answer uses the same technique as yours except that it grabs the last character directly rather than based on matching a regular expression. I suspect most people would find that solution more readable; I know I did.
Mike Graham
@Mike: There are more than one way to solve a problem, and I've learned that it's good to adopt the unix philosophy of being forgiving in your input and precise in output.... This example shows that the regex can pull out the formatted numbers even with noise characters such as ' ' and ',', and even extracts many such numbers from the input with very little additional work. The other solution solves the problem but is more "brittle".
Joe Koberg
+1  A: 

You might be interested in a units library like quantities or unum.

Mike Graham
A: 

Using lambda:

>>> tens = {'k': 10e3, 'm': 10e6, 'b': 10e9}
>>> f = lambda x: int(float(x[:-1])*tens[x[-1]])
>>> f('1.7m')
17000000
>>> f('1.8k')
18000
>>> f('1.2b')
12000000000
Selinap