2

I need to truncate / round / justify all the elements of a list to 8 characters. The input list can contain int (that are never too long), str (that I can truncate) and floats as float float64 or str.

Below is a sample of my code :

data = [12452, "too much characters", 0.12457544512, -0.12457544512, "-1245154.8"] processedData = [] for d in data: processedValue = str(d) if len(processedValue) > 8 and '.' in processedValue: decIndex = processedValue.index(".") processedValue = str(round(float(processedValue), 8 - (decIndex + 1))) elif len(processedValue) > 8: processedValue = processedValue[:8] processedData.append(processedValue.rjust(8, " ")) print(processedData) 

The output and desired output :

[' 12452', 'too much', '0.124575', '-0.12458', '-1245150.0'] # Output [' 12452', 'too much', '0.124575', '-0.12458', '-1245155'] # Desired Output 

When the decimal is near the end of the 8 characters, my values are not rounded at the correct index. When I replace the elif condition by if, the length is correct but the last digit is still wrong. I've tried some other changes ending up in introducing errors for the other values.

0

2 Answers 2

3

I would use f-strings for string formatting. As the other user already answered check for the type:

  • using isinstance() builtin function
  • a custom defined function is_float(s) that returns True if value or string can be converted to float (without exception).

Then you can left-pad to a fixed-width string of 8 characters with the format literal :8 and even round-up to an integer representation with 0 decimal places using :.0f. Or use both combined: :8.0f - all inside the curly-braces appended to the expression to format (here: d or converted float(d)):

f"{float(d):8.0f}" if isinstance(d, float) or is_float(d) else f"{d:8}"

Including a bit debug-prints at the beginning:

import math data = [12452, "too much characters", 0.12457544512, -0.12457544512, "-1245154.8"] print(f"input: {data}") print(f"dt: {[type(d) for d in data]}") def is_float(s): try: float(s) except ValueError: return False return True processedData = [] for d in data: processedValue = f"{float(d):8.0f}" if isinstance(d, float) or is_float(d) else f"{d:8}" print(processedValue) if len(processedValue) > 8 and '.' in processedValue: decIndex = processedValue.index(".") processedValue = str(round(float(processedValue), 8 - (decIndex + 1))) elif len(processedValue) > 8: processedValue = processedValue[:8] processedData.append(processedValue.rjust(8, " ")) print(f"output: {processedData}") 

Prints as final line the expected:

input: [12452, 'too much characters', 0.12457544512, -0.12457544512, '-1245154.8'] dt: [<class 'int'>, <class 'str'>, <class 'float'>, <class 'float'>, <class 'str'>] 12452 too much characters 0 -0 -1245155 output: [' 12452', 'too much', ' 0', ' -0', '-1245155'] 

See also:

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, I guess the is_float() function is somehow what I was looking for, allowing to test equally float float64 and str containing a float.
This is very smart, would not have thought of that.
1

I guess this is one way to fix it with the current data. Results may vary depending on the input.

data = [12452, "too much characters", 0.12457544512, -0.12457544512, "-1245154.8"] processedData = [] for entry in data: try: entry = float(entry) except ValueError: pass if isinstance(entry, float): rounded = round(entry) if rounded == 0: entry = round(entry,8-(str(entry).index(".")+1)) else: entry = rounded entry = str(entry)[:8] processedData.append(entry.rjust(8, " ")) print(processedData) 

Result:

[' 12452', 'too much', '0.124575', '-0.12458', '-1245155'] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.