Como formatar um flutuador para que não contenha zeros à direita? Em outras palavras, quero que a sequência resultante seja a mais curta possível.
Por exemplo:
3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"
Como formatar um flutuador para que não contenha zeros à direita? Em outras palavras, quero que a sequência resultante seja a mais curta possível.
Por exemplo:
3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"
3.14 == 3.140
- Eles são o mesmo número de ponto flutuante. Para esse assunto, 3.140000 é o mesmo número de ponto flutuante. O zero não existe em primeiro lugar.%0.2f
e%0.3f
são os dois formatos necessários para produzir os últimos números à esquerda. Use%0.2f
para produzir os dois últimos números à direita.3.0 -> "3"
ainda é um caso de uso válido.print( '{:,g}'.format( X )
trabalhou para eu produzir3
ondeX = 6 / 2
e quandoX = 5 / 2
obtive uma saída2.5
conforme o esperado.print("%s"%3.140)
dá o que você quer. (Eu adicionei uma resposta para baixo abaixo ...)Respostas:
Eu, eu faria
('%f' % x).rstrip('0').rstrip('.')
- garante a formatação de ponto fixo em vez de notação científica, etc. etc. Sim, não tão elegante e elegante quanto%g
, mas funciona (e não sei como forçar%g
a nunca usar notação científica; -)fonte
'%.2f' % -0.0001
deixá-lo com-0.00
e, finalmente-0
.'f' Fixed point. Displays the number as a fixed-point number. The default precision is 6.
você precisaria usar '% 0.7f' na solução acima.'%0.15f'
é uma má ideia, porque coisas estranhas começam a acontecer.print('In the middle {} and something else'.format('{:f}'.format(a).rstrip('0')))
rstrip
comando. Use simplesmente esta vez para retirar tanto o ponto (.
) e todos os zeros à direita depois em uma única operação:('%f' % x).rstrip('.0')
Você pode usar
%g
para conseguir isso:ou, para Python 2.6 ou melhor:
Dos documentos para
format
:g
causas (entre outras coisas)fonte
'{0:...}'.format(value)
quando você poderia usarformat(value, '...')
? Isso evita a necessidade de analisar o especificador de formato de uma sequência de modelos que, de outra forma, está vazia.format(v, '2.5f')
demoraram cerca de 10% a mais que'{:2.5f}'.format(v)
. Mesmo se não, eu costumo usar ostr
formulário do método, porque quando preciso ajustá-lo, adicionar valores adicionais etc., há menos alterações. Obviamente, a partir de 3.6, temos f-strings para a maioria dos propósitos. :-)f"{var:g}"
ondevar
está uma variável float.Que tal tentar a abordagem mais fácil e provavelmente mais eficaz? O método normalize () remove todos os zeros à direita.
Funciona em Python 2 e Python 3 .
-- Atualizada --
O único problema como @ BobStein-VisiBone apontou é que números como 10, 100, 1000 ... serão exibidos em representação exponencial. Isso pode ser facilmente corrigido usando a seguinte função:
fonte
Decimal('10.0').normalize()
se torna'1E+1'
Depois de examinar as respostas para várias perguntas semelhantes, esta parece ser a melhor solução para mim:
Meu raciocínio:
%g
não se livra da notação científica.15 casas decimais parecem evitar comportamentos estranhos e têm muita precisão para minhas necessidades.
Eu poderia ter usado em
format(inputValue, '.15f').
vez de'%.15f' % inputValue
, mas isso é um pouco mais lento (~ 30%).Eu poderia ter usado
Decimal(inputValue).normalize()
, mas isso também tem alguns problemas. Por um lado, é MUITO mais lento (~ 11x). Também descobri que, embora tenha uma precisão bastante grande, ainda sofre perda de precisão ao usá-lonormalize()
.Mais importante, eu ainda estaria convertendo para
Decimal
de umfloat
que pode fazer com que você acabe com algo diferente do número que você coloca lá. Eu acho queDecimal
funciona melhor quando a aritmética permaneceDecimal
eDecimal
é inicializada com uma string.Tenho certeza de que a questão da precisão de
Decimal.normalize()
pode ser ajustada ao que é necessário usando configurações de contexto, mas considerando a velocidade já baixa e não precisando de precisão ridícula e o fato de que eu ainda estaria convertendo de um flutuador e perdendo a precisão de qualquer maneira, eu não acho que valeu a pena perseguir.Não estou preocupado com o possível resultado "-0", já que -0.0 é um número de ponto flutuante válido e provavelmente seria uma ocorrência rara, mas como você mencionou que deseja manter o resultado da string o mais curto possível, você sempre poderia usar um condicional extra com muito pouco custo de velocidade extra.
fonte
floatToString(12345.6)
retorna'12345.600000000000364'
por exemplo. Diminuir 15 in%.15f
para um número menor resolve-o neste exemplo, mas esse valor precisa ser diminuído cada vez mais à medida que o número aumenta. Pode ser calculado dinamicamente com base na base 10 do log do número, mas isso rapidamente se torna muito complicado.result = ('%15f' % val).rstrip('0').rstrip('.').lstrip(' ')
>>>12345.600000000000364 == 12345.6
True
Aqui está uma solução que funcionou para mim. É uma mistura da solução do PolyMesh e o uso da nova
.format()
sintaxe .Saída :
fonte
3.141
), pois.2f
é codificado.Você pode simplesmente usar format () para conseguir isso:
format(3.140, '.10g')
onde 10 é a precisão que você deseja.fonte
fonte
int(a) if a % 1 else a
?a if a % 1 else int(a)
está correto. Pergunta precisa de saída em string, então acabei de adicionarstr
a % 1
é verdade porque é diferente de zero. Eu implícita e erroneamente percebi issoa % 1 == 0
.Embora seja provável que a formatação seja a forma mais Pythonic, aqui está uma solução alternativa usando a
more_itertools.rstrip
ferramenta.O número é convertido em uma sequência, sem caracteres finais que atendem a um predicado. A definição da função
fmt
não é necessária, mas é usada aqui para testar asserções, todas aprovadas. Nota: funciona em entradas de sequência e aceita predicados opcionais.Veja também detalhes nesta biblioteca de terceiros
more_itertools
,.fonte
Se você pode viver com 3. e 3.0 aparecendo como "3.0", uma abordagem muito simples que retira zeros à direita das representações flutuantes:
(obrigado @ellimilial por apontar as exceções)
fonte
print("%s"%3.0)
faz.Usar o pacote QuantiPhy é uma opção. Normalmente, o QuantiPhy é usado ao trabalhar com números com unidades e fatores de escala de SI, mas possui diversas opções de formatação de números.
E não usará notação eletrônica nesta situação:
Uma alternativa que você pode preferir é usar fatores de escala de SI, talvez com unidades.
fonte
O OP gostaria de remover zeros supérfluos e tornar a string resultante o mais curta possível.
Acho que a formatação exponencial% g reduz a cadeia resultante para valores muito grandes e muito pequenos. O problema ocorre com valores que não precisam de notação exponencial, como 128.0, que não é muito grande nem muito pequena.
Aqui está uma maneira de formatar números como cadeias curtas que usam a notação exponencial% g somente quando Decimal.normalize cria cadeias muito longas. Esta pode não ser a solução mais rápida (pois usa Decimal.normalize)
fonte
Para float você pode usar isso:
Teste-o:
Para Decimal, consulte a solução aqui: https://stackoverflow.com/a/42668598/5917543
fonte
"{:.5g}".format(x)
Eu uso isso para formatar carros alegóricos para rastrear zeros.
fonte
Aqui está a resposta:
saída "3.14" e "3"
trim='-'
remove os zeros à direita e os decimais.fonte
Use% g com largura grande o suficiente, por exemplo '% .99g'. Ele será impresso em notação de ponto fixo para qualquer número razoavelmente grande.
EDIT: não funciona
fonte
.99
é precisão, não largura; meio útil, mas você não pode definir a precisão real dessa maneira (exceto truncá-la você mesmo).Você pode usar
max()
assim:print(max(int(x), x))
fonte
x
é negativo.if x < 0: print(min(x), x)
else : print(max(x), x)
Você pode conseguir isso da maneira mais pitônica possível:
python3:
fonte
Manuseando% f e você deve colocar
, onde: .2f == .00 flutua.
Exemplo:
imprimir "Preço:% .2f"% preços [produto]
resultado:
Preço: 1.50
fonte