Jak sformatować liczbę zmiennoprzecinkową, aby nie zawierała zer na końcu? Innymi słowy, chcę, aby wynikowy ciąg był jak najkrótszy.
Na przykład:
3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"
Jak sformatować liczbę zmiennoprzecinkową, aby nie zawierała zer na końcu? Innymi słowy, chcę, aby wynikowy ciąg był jak najkrótszy.
Na przykład:
3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"
3.14 == 3.140
- Są to te same liczby zmiennoprzecinkowe. W tym przypadku 3.140000 to ta sama liczba zmiennoprzecinkowa. Zero nie istnieje w ogóle.%0.2f
i%0.3f
są dwoma formatami wymaganymi do utworzenia ostatnich liczb po lewej stronie. Użyj,%0.2f
aby utworzyć dwie ostatnie cyfry po prawej stronie.3.0 -> "3"
jest nadal ważnym przypadkiem użycia.print( '{:,g}'.format( X )
pracował dla mnie, aby uzyskać dane wyjściowe3
tam, gdzieX = 6 / 2
i kiedyX = 5 / 2
otrzymałem wynik zgodny z2.5
oczekiwaniami.print("%s"%3.140)
daje ci to, czego chcesz. (Dodałem odpowiedź poniżej ...)Odpowiedzi:
Ja, zrobiłbym
('%f' % x).rstrip('0').rstrip('.')
- gwarantuje formatowanie stałoprzecinkowe zamiast notacji naukowej itp. Tak, nie jest tak elegancki i elegancki%g
, ale działa, (i nie wiem, jak zmusić,%g
aby nigdy nie używać notacji naukowej; -).źródło
'%.2f' % -0.0001
to, że-0.00
ostatecznie cię opuści-0
.'f' Fixed point. Displays the number as a fixed-point number. The default precision is 6.
W powyższym rozwiązaniu musiałbyś użyć „% 0.7f”.'%0.15f'
jest złym pomysłem, ponieważ zaczynają się dziać dziwne rzeczy .print('In the middle {} and something else'.format('{:f}'.format(a).rstrip('0')))
rstrip
polecenia. Po prostu użyj tego zamiast tego, aby usunąć zarówno kropkę (.
), jak i wszystkie końcowe zera w jednej operacji:('%f' % x).rstrip('.0')
Możesz to
%g
osiągnąć:lub w przypadku Python 2.6 lub nowszego:
Z dokumentacji dotyczącej
format
:g
przyczyn (między innymi)źródło
'{0:...}'.format(value)
Po co korzystać, kiedy można korzystaćformat(value, '...')
? Pozwala to uniknąć konieczności analizowania specyfikatora formatu z ciągu szablonu, który w innym przypadku byłby pusty.format(v, '2.5f')
zajęły ~ 10% dłużej niż'{:2.5f}'.format(v)
. Nawet jeśli tak się nie stało, zwykle używamstr
formularza metody, ponieważ kiedy muszę go ulepszyć, dodać do niego dodatkowe wartości itp., Jest mniej do zmiany. Oczywiście od wersji 3.6 mamy większość strun f-string. :-)f"{var:g}"
gdzievar
jest zmienną pływak.Co powiesz na wypróbowanie najłatwiejszego i prawdopodobnie najbardziej skutecznego podejścia? Metoda normalize () usuwa wszystkie skrajne po prawej stronie zera.
Działa w Python 2 i Python 3 .
- Zaktualizowano -
Jedynym problemem, jak wskazał @ BobStein-VisiBone, jest to, że liczby takie jak 10, 100, 1000 ... będą wyświetlane w postaci wykładniczej. Można to łatwo naprawić za pomocą następującej funkcji:
źródło
Decimal('10.0').normalize()
staje się'1E+1'
Po przejrzeniu odpowiedzi na kilka podobnych pytań wydaje mi się to najlepszym rozwiązaniem:
Moje rozumowanie:
%g
nie pozbywa się notacji naukowej.15 miejsc po przecinku wydaje się unikać dziwnego zachowania i ma dużą precyzję na moje potrzeby.
Mógłbym użyć
format(inputValue, '.15f').
zamiast'%.15f' % inputValue
, ale to trochę wolniej (~ 30%).Mógłbym użyć
Decimal(inputValue).normalize()
, ale ma to również kilka problemów. Po pierwsze, jest DUŻO wolniejszy (~ 11x). Odkryłem również, że chociaż ma dość dużą precyzję, nadal cierpi z powodu utraty precyzji podczas używanianormalize()
.Co najważniejsze, nadal będę się zmieniał
Decimal
z tego,float
co może sprawić, że skończysz na czymś innym niż liczba, którą tam umieściłeś. Myślę, żeDecimal
działa najlepiej, gdy arytmetyka pozostaje w środkuDecimal
iDecimal
jest inicjalizowana ciągiem znaków.Jestem pewien, że kwestię precyzji
Decimal.normalize()
można dopasować do tego, co jest potrzebne przy użyciu ustawień kontekstowych, ale biorąc pod uwagę już małą prędkość i niepotrzebną niedorzeczną precyzję, a także fakt, że i tak będę konwertować z liczby zmiennoprzecinkowej i tracę precyzję, nie zrobiłem tego nie sądzę, że warto było to kontynuować.Nie przejmuję się możliwym wynikiem „-0”, ponieważ -0.0 jest prawidłową liczbą zmiennoprzecinkową i prawdopodobnie byłoby to rzadkie zjawisko, ale ponieważ wspomniałeś, że chcesz, aby wynik łańcucha był jak najkrótszy, zawsze może zastosować dodatkowy warunek przy bardzo niewielkim koszcie dodatkowej prędkości.
źródło
floatToString(12345.6)
zwraca'12345.600000000000364'
na przykład. Zmniejszenie 15%.15f
do mniejszej liczby rozwiązuje to w tym przykładzie, ale wartość ta musi być zmniejszana coraz bardziej, gdy liczba staje się większa. Może być obliczany dynamicznie na podstawie log-base-10 liczby, ale szybko staje się to bardzo skomplikowane.result = ('%15f' % val).rstrip('0').rstrip('.').lstrip(' ')
>>>12345.600000000000364 == 12345.6
True
Oto rozwiązanie, które zadziałało dla mnie. Jest to mieszanka roztworu przez PolyMesh i stosowania nowej
.format()
składni .Wyjście :
źródło
3.141
), Ponieważ.2f
jest na stałe zakodowany.Aby to osiągnąć, możesz po prostu użyć formatu ():
format(3.140, '.10g')
gdzie 10 to pożądana precyzja.źródło
źródło
int(a) if a % 1 else a
?a if a % 1 else int(a)
jest poprawne. Pytanie wymaga danych wyjściowych w ciągu, więc właśnie dodałemstr
a % 1
jest prawdą, ponieważ jest niezerowe. Ja domyślnie i błędnie postrzegałem to jakoa % 1 == 0
.Podczas gdy formatowanie jest prawdopodobne w większości Pythonów, tutaj jest alternatywne rozwiązanie za pomocą tego
more_itertools.rstrip
narzędzia.Liczba jest konwertowana na ciąg, który jest pozbawiony końcowych znaków, które spełniają predykat. Definicja funkcji
fmt
nie jest wymagana, ale służy tutaj do testowania twierdzeń, które wszystkie przekazują. Uwaga: działa na wejściach łańcuchowych i akceptuje predykaty opcjonalne.Zobacz także szczegółowe informacje na temat tej biblioteki stron trzecich,
more_itertools
.źródło
Jeśli możesz żyć z wersjami 3. i 3.0 wyświetlanymi jako „3.0”, bardzo proste podejście, które usuwa zera z pływających reprezentacji:
(dzięki @ellimilial za wskazanie wyjątków)
źródło
print("%s"%3.0)
robi.Korzystanie z pakietu QuantiPhy jest opcją. Zazwyczaj QuantiPhy jest używane podczas pracy z liczbami z jednostkami i współczynnikami skali SI, ale ma wiele fajnych opcji formatowania liczb.
I nie będzie używać notacji elektronicznej w tej sytuacji:
Alternatywą, którą możesz preferować, jest użycie współczynników skali SI, być może z jednostkami.
źródło
OP chce usunąć zbędne zera i uczynić otrzymany ciąg tak krótkim, jak to możliwe.
Uważam, że formatowanie wykładnicze% g skraca wynikowy ciąg znaków dla bardzo dużych i bardzo małych wartości. Problem pojawia się w przypadku wartości, które nie wymagają notacji wykładniczej, takich jak 128.0, która nie jest ani bardzo duża, ani bardzo mała.
Oto jeden ze sposobów formatowania liczb jako krótkich ciągów, które wykorzystują notację wykładniczą% g tylko wtedy, gdy Decimal.normalize tworzy ciągi, które są zbyt długie. To może nie być najszybsze rozwiązanie (ponieważ używa Decimal.normalize)
źródło
Dla float możesz użyć tego:
Sprawdź to:
W przypadku systemu dziesiętnego zobacz rozwiązanie tutaj: https://stackoverflow.com/a/42668598/5917543
źródło
"{:.5g}".format(x)
Używam tego do formatowania liczb zmiennoprzecinkowych do śledzenia zer.
źródło
Oto odpowiedź:
wyjście „3.14” i „3”
trim='-'
usuwa zarówno końcowe zera, jak i dziesiętne.źródło
Użyj% g o wystarczająco dużej szerokości, na przykład „% .99g”. Będzie drukowany w notacji stałej dla dowolnej dość dużej liczby.
EDYCJA: to nie działa
źródło
.99
to precyzja, a nie szerokość; jest to przydatne, ale nie można w ten sposób ustawić rzeczywistej precyzji (poza obcięciem jej samodzielnie).Możesz użyć w
max()
ten sposób:print(max(int(x), x))
źródło
x
jest negatywny.if x < 0: print(min(x), x)
else : print(max(x), x)
Możesz to osiągnąć w najbardziej pythonowy sposób:
python3:
źródło
Obsługa% f i powinieneś umieścić
, gdzie: .2f == .00 zmiennoprzecinkowe.
Przykład:
drukuj „Cena:% .2f”% ceny [produkt]
wynik:
Cena: 1,50
źródło