0으로 끝나지 않고 파이썬에서 부동 형식화
후행 0을 포함하지 않도록 float을 어떻게 포맷 할 수 있습니까? 즉, 결과 문자열을 가능한 짧게 만들고 싶습니다.
예를 들면 다음과 같습니다.
3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"
저도 할 것입니다 ('%f' % x).rstrip('0').rstrip('.')
-과학적 표기법 등이 아닌 고정 소수점 형식을 보장합니다. 예, 매끄럽고 우아 %g
하지는 않지만 작동합니다 %g
. -).
%g
이것을 달성하기 위해 사용할 수 있습니다 :
'%g'%(3.140)
또는 파이썬 2.6 이상의 경우 :
'{0:g}'.format(3.140)
보내는 사람 에 대한 문서format
: g
(무엇보다도) 원인
중요하지 않은 후행 0은 [유의]에서 제거되며 그 뒤에 남은 자릿수가 없으면 소수점도 제거됩니다.
가장 쉽고 아마도 가장 효과적인 접근법을 시도하는 것은 어떻습니까? normalize () 메소드 는 가장 오른쪽에있는 모든 0을 제거합니다.
from decimal import Decimal
print (Decimal('0.001000').normalize())
# Result: 0.001
Python 2 및 Python 3 에서 작동합니다 .
-업데이트-
@ BobStein-VisiBone이 지적한 유일한 문제는 10, 100, 1000 ...과 같은 숫자가 지수 표현으로 표시된다는 것입니다. 대신 다음 기능을 사용하여 쉽게 고칠 수 있습니다.
from decimal import Decimal
def format_float(f):
d = Decimal(str(f));
return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
몇 가지 유사한 질문에 대한 답변을 살펴본 후에 이것은 가장 좋은 해결책 인 것 같습니다.
def floatToString(inputValue):
return ('%.15f' % inputValue).rstrip('0').rstrip('.')
내 추론 :
%g
과학적 표기법을 제거하지 않습니다.
>>> '%g' % 0.000035
'3.5e-05'
소수 자릿수 15 자리는 이상한 행동을 피하는 것으로 보이며 내 요구에 충분한 정밀도를 가지고 있습니다.
>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'
format(inputValue, '.15f').
대신 사용할 수는 '%.15f' % inputValue
있지만 조금 느립니다 (~ 30 %).
사용할 수는 Decimal(inputValue).normalize()
있지만 몇 가지 문제가 있습니다. 하나, 그것은 훨씬 더 느립니다 (~ 11x). 또한 정확도가 매우 뛰어나지 만 사용할 때 여전히 정밀도 손실이 발생한다는 것을 알았습니다 normalize()
.
>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')
가장 중요한 것은, 나는 여전히 당신이 거기에 넣은 숫자가 아닌 다른 것으로 끝날 수있는 Decimal
에서 로 변환 할 float
것입니다. 내가 생각하는 Decimal
일을 가장 잘 할 때 산술에서 숙박 Decimal
하고이 Decimal
문자열로 초기화됩니다.
>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')
Decimal.normalize()
컨텍스트 설정을 사용하여 필요한 것에 대한 정밀도 문제를 조정할 수 있다고 확신 하지만 이미 느린 속도와 어리석은 정밀도가 필요하지 않고 여전히 부동에서 변환하고 정밀도를 잃어 가고 있다는 사실을 고려하면 추구 할 가치가 있다고 생각하지 않습니다.
I'm not concerned with the possible "-0" result since -0.0 is a valid floating point number and it would probably be a rare occurrence anyway, but since you did mention you want to keep the string result as short as possible, you could always use an extra conditional at very little extra speed cost.
def floatToString(inputValue):
result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
return '0' if result == '-0' else result
Here's a solution that worked for me. It's a blend of the solution by PolyMesh and use of the new .format()
syntax.
for num in 3, 3., 3.0, 3.1, 3.14, 3.140:
print('{0:.2f}'.format(num).rstrip('0').rstrip('.'))
Output:
3
3
3
3.1
3.14
3.14
You can simply use format() to achieve this:
format(3.140, '.10g')
where 10 is the precision you want.
>>> str(a if a % 1 else int(a))
While formatting is likely that most Pythonic way, here is an alternate solution using the more_itertools.rstrip
tool.
import more_itertools as mit
def fmt(num, pred=None):
iterable = str(num)
predicate = pred if pred is not None else lambda x: x in {".", "0"}
return "".join(mit.rstrip(iterable, predicate))
assert fmt(3) == "3"
assert fmt(3.) == "3"
assert fmt(3.0) == "3"
assert fmt(3.1) == "3.1"
assert fmt(3.14) == "3.14"
assert fmt(3.140) == "3.14"
assert fmt(3.14000) == "3.14"
assert fmt("3,0", pred=lambda x: x in set(",0")) == "3"
The number is converted to a string, which is stripped of trailing characters that satisfy a predicate. The function definition fmt
is not required, but it is used here to test assertions, which all pass. Note: it works on string inputs and accepts optional predicates.
See also details on this third-party library, more_itertools
.
If you can live with 3. and 3.0 appearing as "3.0", a very simple approach that right-strips zeros from float representations:
print("%s"%3.140)
(thanks @ellimilial for pointing out the exceptions)
OP would like to remove superflouous zeros and make the resulting string as short as possible.
I find the %g exponential formatting shortens the resulting string for very large and very small values. The problem comes for values that don't need exponential notation, like 128.0, which is neither very large or very small.
Here is one way to format numbers as short strings that uses %g exponential notation only when Decimal.normalize creates strings that are too long. This might not be the fastest solution (since it does use Decimal.normalize)
def floatToString (inputValue, precision = 3):
rc = str(Decimal(inputValue).normalize())
if 'E' in rc or len(rc) > 5:
rc = '{0:.{1}g}'.format(inputValue, precision)
return rc
inputs = [128.0, 32768.0, 65536, 65536 * 2, 31.5, 1.000, 10.0]
outputs = [floatToString(i) for i in inputs]
print(outputs)
# ['128', '32768', '65536', '1.31e+05', '31.5', '1', '10']
For float you could use this:
def format_float(num):
return ('%i' if num == int(num) else '%s') % num
Test it:
>>> format_float(1.00000)
'1'
>>> format_float(1.1234567890000000000)
'1.123456789'
For Decimal see solution here: https://stackoverflow.com/a/42668598/5917543
Use %g with big enough width, for example '%.99g'. It will print in fixed-point notation for any reasonably big number.
EDIT: it doesn't work
>>> '%.99g' % 0.0000001
'9.99999999999999954748111825886258685613938723690807819366455078125e-08'
You can use max()
like this:
print(max(int(x), x))
You can achieve that in most pythonic way like that:
python3:
"{:0.0f}".format(num)
Handling %f and you should put
%.2f
, where: .2f == .00 floats.
Example:
print "Price: %.2f" % prices[product]
output:
Price: 1.50
참고URL : https://stackoverflow.com/questions/2440692/formatting-floats-in-python-without-trailing-zeros
'Programing' 카테고리의 다른 글
1-10 Java 사이의 난수 생성 (0) | 2020.06.05 |
---|---|
날짜 시간을 유닉스 타임 스탬프로 변환하고 파이썬으로 다시 변환하십시오. (0) | 2020.06.05 |
Python Django에서 단위 테스트를 실행하는 동안 로깅을 비활성화하려면 어떻게합니까? (0) | 2020.06.05 |
Python 문서에 javadoc 사용하기 (0) | 2020.06.05 |
Array.Add vs + = (0) | 2020.06.05 |