2010-10-11 10 views

Respuesta

87

Nadie hasta ahora ha mencionado la nueva opción ',' que se añadió en la versión 2.7 de la especificación de formato Mini-Lenguaje - ver PEP 378: Format Specifier for Thousands Separator en el What's New in Python 2.7 document. Es fácil de usar porque no tiene que perder el tiempo con locale (pero está limitado para la internacionalización debido a eso, consulte el original PEP 378). Funciona con flotantes, enteros y decimales, y todas las demás características de formato previstas en la especificación de mini-idioma.

Ejemplo de uso:

print format(1234, ",d") # -> 1,234 
print "{:,d}".format(1234) # -> 1,234 

Nota: Aunque esta innovación es, sin duda muy útil, en realidad no todo lo que mucho más difícil de usar el módulo locale, como varios otros han sugerido. La ventaja es que la salida numérica se puede hacer para seguir automáticamente las convenciones de separador de miles (y otras) adecuadas que se utilizan en varios países al generar datos como números, fechas y horas. También es muy fácil poner en práctica las configuraciones predeterminadas de su computadora sin aprender un montón de códigos de idioma y país. Todo lo que necesita hacer es:

import locale 
locale.setlocale(locale.LC_ALL, '') # empty string for platform's default settings 

Después de hacer eso sólo puede utilizar el código 'n' tipo genérico para los números enteros (tanto float) y la salida.¿Dónde estoy, comas se utilizan como separador de miles, por lo que después de establecer la configuración regional como se muestra arriba, esto es lo que sucedería:

print format(1234, "n") # -> 1,234 
print "{:n}".format(1234) # -> 1,234 

Gran parte del resto del mundo utiliza los períodos en lugar de comas para este fin, por lo que establecer la configuración regional predeterminada en muchos lugares (o especificar explícitamente el código para una región tal en una llamada setlocale()) produce los siguientes:

print format(1234, "n") # -> 1.234 
print "{:n}".format(1234) # -> 1.234 

de salida basándose en el tipo especificador 'd' o ',d' formato no se ve afectado por el uso (o no uso) de setlocale(). Sin embargo, el 'd' especificador es afectado si en su lugar utiliza las funciones locale.format() o locale.format_string().

+3

-1 Desafortunadamente esto está ** roto **; perpetúa la legacyness del módulo local - ** no funciona correctamente con Unicode **. Pruebe 'format (1234, u" n ")' en una configuración regional (por ejemplo, francés, ruso) donde el separador de miles es un ESPACIO SIN INTERRUPCIÓN. Usted obtiene la excepción favorita de los novatos: 'UnicodeDecodeError: códec 'ascii' no puede decodificar byte 0xa0 ...' –

+1

@John Machin: Para el registro, la mayoría de los upvotes se hicieron a esta respuesta antes de agregar la Nota sobre el uso 'locale' - y para la iluminación de todos, ¿qué * es * el motivo correcto actual para la operación en una configuración regional específica que manejará Unicode? Gracias. – martineau

+0

(1) ¿Cuándo se hicieron las votaciones ascendentes es de qué relevancia? (2) No hay iluminación soportada por Python-2.X, solo un formato kludge: '(1234," n "). Decodificación (locale.getpreferredencoding())' :-( –

13

locale.format()

No se olvide de establecer la configuración regional apropiada primero.

+0

Y no se olvide de especificar un valor 'True' para el argumento opcional _grouping_, como en' locale.format (u '% d', 1234, True) 'por ejemplo. Aparentemente 'locale' no es completamente inepto en el manejo de Unicode (como sugieren los comentarios de John Machin en otra respuesta). – martineau

10

despojados de webpyutils.py:

def commify(n): 
    """ 
    Add commas to an integer `n`. 

     >>> commify(1) 
     '1' 
     >>> commify(123) 
     '123' 
     >>> commify(1234) 
     '1,234' 
     >>> commify(1234567890) 
     '1,234,567,890' 
     >>> commify(123.0) 
     '123.0' 
     >>> commify(1234.5) 
     '1,234.5' 
     >>> commify(1234.56789) 
     '1,234.56789' 
     >>> commify('%.2f' % 1234.5) 
     '1,234.50' 
     >>> commify(None) 
     >>> 

    """ 
    if n is None: return None 
    n = str(n) 
    if '.' in n: 
     dollars, cents = n.split('.') 
    else: 
     dollars, cents = n, None 

    r = [] 
    for i, c in enumerate(str(dollars)[::-1]): 
     if i and (not (i % 3)): 
      r.insert(0, ',') 
     r.insert(0, c) 
    out = ''.join(r) 
    if cents: 
     out += '.' + cents 
    return out 

hay otras soluciones here.

+0

+1 a pesar de la docstring, parece que maneja números en coma flotante así como en números enteros. El uso de los nombres de variables "dólares" y "centavos", además de centrarse demasiado en las aplicaciones, parece respaldar esta hipótesis. La versión portátil de Python, tal como se presentó, volverá a la versión 2.3, y si el iterador 'enumerate()' fue reemplazado por algo equivalente, todo el camino de vuelta a la versión 2.0. – martineau

+1

Para Python 2.4+, el 'str (dólares) [:: - 1]' podría ser reemplazado por el más legible 'invertido (str (dólares))'. – martineau

+0

Buena reseña de @martineau, uso esta función en Google App Engine, donde Python está limitado a la versión 2.5 de fábrica. – systempuntoout

4

Use locale.format() en el número entero, pero tenga cuidado con la configuración regional actual en su entorno. Algunos entornos pueden no tener este conjunto o establecerse en algo que no le dará un resultado de coma.

Aquí hay un código que tuve que escribir para tratar este tema exacto. Va ajusta automáticamente la configuración regional para usted dependiendo de su plataforma:

try: 
    locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') #use locale.format for commafication 
except locale.Error: 
    locale.setlocale(locale.LC_ALL, '') #set to default locale (works on windows) 

score = locale.format('%d', player['score'], True) 
Cuestiones relacionadas