Reputation: 1674
I need some strings of floats in scientific notation such as ['5e-6','1e-5','1.5e-5','2e-5','2.5e-5',...]
.
So I try to generate them with [str(n*1e-6) for n in list(range(5,60,5))]
yet it gives ['4.9999999999999996e-06', '9.999999999999999e-06', '1.4999999999999999e-05',...]
.
Then I try to format them with ["{:.1e}".format(n*1e-6) for n in list(range(5,60,5))]
and it gives ['5.0e-06', '1.0e-05', '1.5e-05', '2.0e-05', '2.5e-05',...]
which are still not what I want.
I wonder is there any simple way to do this other than writing a custom function? Thanks.
Upvotes: 1
Views: 462
Reputation: 4744
This works for your specific example, but note that it's quite hardcoded:
["{:.0e}".format(n*1e-6) if not n%10 or n<10 else "{:.1e}".format(n*1e-6) for n in list(range(5,60,5))]
Here you change the format for numbers that you don't want to display with any decimal part, but you still display the x.5 numbers properly. The code makes an exception for 5, otherwise it would be printed with a decimal.
This is a version that fully addresses your question - it also removes the trailing 0 in the exponent:
["{:.0e}".format(n*1e-6).replace("e-0", "e-") if not n%10 or n<10 else "{:.1e}".format(n*1e-6).replace("e-0", "e-") for n in list(range(5,60,5))]
replace
trick comes from this post - as stated in there, you'd need to extend it for e+0
.
Upvotes: 1
Reputation: 25490
You could just replace the .0e
part with e
.
["{:.1e}".format(n*1e-6).replace(".0e", "e") for n in list(range(5,60,5))]
This gives
['5e-06', '1e-05', '1.5e-05', '2e-05', '2.5e-05', '3e-05', '3.5e-05', '4e-05', '4.5e-05', '5e-05', '5.5e-05']
Which still leaves us with the leading zero in the exponent. To get rid of that, we can use a regular expression:
(e-?)0(\d+)
Explanation: https://regex101.com/r/8bXvDH/1
(e-?)
: Match a literal e
followed by an optional minus sign. Capturing group 10
: Match a literal zero(\d+)
: Match one or more digits. Capturing group 2.To do the substitution, we use re.sub()
:
# \1\2 in the replace string means capturing group 1, then capturing group 2
re.sub(r"(e-?)0(\d+)", r"\1\2", "5e-06") # Gives "5e-6"
In our list compregension:
[re.sub(r"(e-?)0(\d+)", r"\1\2", "{:.1e}".format(n*1e-6).replace(".0e", "e")) for n in list(range(5,60,5))]
gives what we want:
['5e-6', '1e-5', '1.5e-5', '2e-5', '2.5e-5', '3e-5', '3.5e-5', '4e-5', '4.5e-5', '5e-5', '5.5e-5']
Upvotes: 1