2014-06-05 1 views
1

Ce que je suis en train d'accomplirLa façon la plus pythonique au pad un flotteur gauche de la virgule

-12.345 -> -012.345 

Où gauche de décimales peut être -999-> 999 (pour mes besoins spécifiques) et n-montant de chiffres décimaux

je suis venu avec deux méthodes pour ce faire:

def pad(num, pad): 
    pad = pow(10,pad) 
    if num > 0: 
     return "%s" % str(num + pad)[1:] 
    else: 
     return "-%s" % str(num - pad)[2:] 

def pad(num, pad): 
    import math 
    mag = 1 + int(math.log10(abs(num))) 
    sz = len(str(num)) 
    return str(num).zfill(pad+sz-mag) 

mais cela semble plutôt obtus pour être python. J'ai vu une question similaire précédente, mais n'a pas aimé la réponse ...

>>> "%06.2f"%3.3 
'003.30' 

car il suppose que vous savez déjà où votre point décimal est et le nombre de chiffres décimaux vous avez.

Cela semble une situation commune, donc est-il un meilleur/plus propre/simple fncall existant, chemin à parcourir à ce sujet dans Python 2.7?

+0

je crois [ '' 'str.format()' ''] (https://docs.python.org/2/library/string.html#formatspec) est ce que vous voulez – wnnmaw

+0

http://stackoverflow.com/questions/17118071/python-add-leading-zeroes-using-str-format ressemble à ça fonctionne bien avec ints mais pas avec les flottants puisque ma largeur est variable en fonction de la quantité de chiffres décimaux, donc de ce que je peux dire, je serais encore besoin de compter le nombre de chiffres décimaux j'ai: \ – pyInTheSky

+2

@pyInTheSky: qu'entendez-vous * quantité de chiffres décimaux *? Les flotteurs sont des * approximations *, vous finissez invariablement par arrondir * de toute façon *. '-12.345' n'est pas * exactement *' -12.345' non plus, par exemple. 'format (-12.345, '.53f')'> ''-12.34500000000000063948846218409016728401184082031250000''. –

Répondre

1

Je ne sais pas si cela est pythonique. Il suffit de remplir un nombre entier et de concaténer la décimale.

def pad(x, p): 
    return ('%0'+str(p+(x<0 and 1 or 0))+'d%s') % (x,str(x-int(x))[x<0 and 2 or 1:]) 

teste

pad(-3,3) -> -003 
pad(3,3) -> 003 
pad(-3.3,3) -> -003.3 
pad(3.3,3) -> 003.3 
+0

@steveha, c'était difficile. Merci de les avoir attrapés – Fabricator

+0

Un bummer qui ne semble pas être assez construit, mais b.a. pour une logique d'épissage fou. Je ne savais pas que cela pouvait être fait. – pyInTheSky

2

Je pense que vous avez trouvé un cas d'angle. Il est facile de spécifier les chiffres à gauche et à droite de la décimale; il est également facile de spécifier le nombre total de chiffres; il n'est pas très facile de spécifier les chiffres à gauche et de laisser les chiffres à droite complètement non spécifiés.

Je suggère que la plus propre chose à faire est de prendre juste la partie entière du flotteur et format, puis prendre la fraction et format (ne pas spécifier une longueur).

est ici une fonction testée qui fait ce que vous avez demandé, et fonctionne aussi correctement pour les nombres négatifs.

import math 

def float_lformat(f, width): 
    neg = f < 0.0 
    fraction, n = math.modf(abs(f)) # get fraction and integer parts of f 
    if neg and width > 0: 
     width -= 1 
    s = "%0*d" % (width, n) + str(fraction)[1:] 
    if neg: 
     s = '-' + s 
    return s 
+0

Oui, je prends un lat NMEA. valeur qui a été convertie de str vers float (en perdant 0 pour le lats <100) et en la remettant en forme plus tard, donc pas la manière la plus commune d'afficher des nombres. – pyInTheSky

0

fixe par rapport à des fractions dynamiques:

>>> "{:08}".format(-12.345) 
'-012.345' 

>>> a,b=str(x).split('.');a=int(a);"{}{:03}.{}".format('-' if a<0 else"",abs(a),b) 
'-012.345' 

assainis:

def pad(x): 
    a, b = str(x).split('.') 
    a = int(a) 
    return '{}{:03}.{}'.format('-' if a < 0 else ' ', abs(a), b) 

for x in [12.0, 12.345, -12.345, -12.3456]: 
    print('{:>8} -> {}'.format(x, pad(x))) 

sortie:

12.0 -> 012.0 
    12.345 -> 012.345 
-12.345 -> -012.345 
-12.3456 -> -012.3456 
Questions connexes