0

Consider the following list of floats:

A = [3.7432, 0.37432, 0.037432, 0.0037432, 0.00037432, 3.4327e-05, \
     3.7432e-06, 3.7432e-07, 3.7432e-08, 3.7432e-09, 3.7432e-10]

I would like to convert these to a list of strings that are (1) rounded to the first significant figure, and (2) are not in scientific notation.

I'm using the following code for this purpose:

[f"{a:.1g}" for a in A]

And this is what I'm getting:

['4', '0.4', '0.04', '0.004', '0.0004', '4e-05', '4e-06', '4e-07', '4e-08', '4e-09', '4e-10',]

However, my desired output would be this:

['4', '0.4', '0.04', '0.004', '0.0004', '0.00004', '0.000004', '0.0000004', '0.00000004', '0.000000004']

My question is, what would be a simple way to achieve this?

Apologies if this is a duplicate. I've gone through a bunch of similar questions but none of them addressed my issue specifically.

EDIT: with the help of @nagyl, I made a function that does what I want:

def float_to_fsf(x):
    """
    Converts float to string with one significant figure
    while refraining from scientific notation

    inputs:
        x: input float to be converted to string (float)
    """

    import numpy as np

    # Get decimal exponent of input float
    exp = int(f"{x:e}".split("e")[1])

    # Get rid of all digits after the first significant figure
    x_fsf = round(x*10**-exp, 0) * 10**exp

    # Get rid of scientific notation and convert to string
    x_str = np.format_float_positional(x_fsf)

    # Return string output
    return x_str
Haliaetus
  • 441
  • 3
  • 11
  • 1
    Similar: https://stackoverflow.com/questions/658763/how-to-suppress-scientific-notation-when-printing-float-values – BowlOfRed Jul 24 '20 at 04:45
  • In the question you linked, they do address scientific notation, but I haven't seen anything about limiting the output to n significant figures. That's the critical element I've been looking for. If it's not clear, please look at my question again, I've made some edits to emphasize. – Haliaetus Jul 24 '20 at 16:36
  • Also related: https://stackoverflow.com/questions/3410976/how-to-round-a-number-to-significant-figures-in-python – BowlOfRed Jul 24 '20 at 16:44
  • I went through the answers and now the case is the opposite. None of them gets rid of scientific notation. I'm in the belief that the issue I'm posing above is unique. In the meantime, @nagyl 's answer helped me come up with an implementation that does what I want. – Haliaetus Jul 24 '20 at 20:22
  • I would combine them. The second link has techniques for rounding to a single significant digit. The first link has techniques for displaying as floating point without trailing zeros. The two combined sounds like what you want. – BowlOfRed Jul 24 '20 at 20:31
  • Right, essentially that's what I did with @nagyl answer. I'm trying to get this user complete their answer so I can accept it. Thank you for your suggestions btw. – Haliaetus Jul 24 '20 at 20:51

1 Answers1

2

You can use format_float_positional from numpy.

for i in range(len(a)):
    a[i] = str(numpy.format_float_positional(a[i]))

Or with list comprehension:

a = [str(numpy.format_float_positional(elem)) for elem in a]
nagyl
  • 1,644
  • 1
  • 7
  • 18
  • Thanks. This takes care of the scientific notation, but not the significant figures. I want a single significant figure. Your solution outputs: `['3.7432', '0.37432', '0.037432', '0.0037432', '0.00037432', '0.000037432', '0.0000037432', '0.00000037432', '0.000000037432', '0.0000000037432', '0.00000000037432']`, My desired output: `['4', '0.4', '0.04', '0.004', '0.0004', '0.00004', '0.000004', '0.0000004', '0.00000004', '0.000000004', '0.0000000004']`. Do you have a solution for this? – Haliaetus Jul 24 '20 at 16:39
  • You can round the number up to a specific digit using round(number, digits) – nagyl Jul 24 '20 at 18:27
  • Okay, after combining the elements you proposed I've made a function that works. I'm adding this function to the end of my question. Your answer is currently incomplete so I'm not accepting it. BUT if you add the function I wrote to your reply (or anything that produces my desired output), I'll accept your reply as the answer and remove the function from the end of my question. My hope is that this will come handy for people in the future. Either way, thanks for your help. – Haliaetus Jul 24 '20 at 20:30