2010-10-11 14 views

risposta

87

Nessuno finora ha accennato al nuovo ',' opzione che è stata aggiunta nella versione 2.7 alla Format Specification Mini-Language - vedere PEP 378: Format Specifier for Thousands Separator nello What's New in Python 2.7 document. È facile da usare perché non devi scherzare con locale (ma è limitato per l'internazionalizzazione a causa di ciò, vedere lo original PEP 378). Funziona con float, ints e decimali e con tutte le altre funzionalità di formattazione previste nelle specifiche di mini-lingua.

utilizzo Esempio:

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

Nota: Mentre questa nuova funzione è sicuramente a portata di mano, in realtà non è tutto ciò che molto più difficile da usare il modulo locale, come molti altri hanno suggerito. Il vantaggio è che quindi è possibile eseguire output numerici per seguire automaticamente le convenzioni dei separatori di migliaia (e di altri) utilizzati in diversi paesi quando si trasmettono informazioni come numeri, date e orari. È anche molto facile mettere in vigore le impostazioni predefinite dal tuo computer senza imparare un sacco di codici di lingua e di paese. Tutto quello che dovete fare è:

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

Dopo aver fatto questo si può semplicemente utilizzare il codice 'n' tipo generico per l'output di numeri (sia interi e float).Dove sono io, le virgole sono utilizzati come il separatore delle migliaia, così dopo l'impostazione della localizzazione, come indicato sopra, questo è ciò che sarebbe accaduto:

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

Gran parte del resto del mondo utilizza periodi invece di virgole per questo scopo, così l'impostazione della localizzazione default in molte località (o specificando esplicitamente il codice per tale regione in una chiamata setlocale()) produce il seguente:

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

uscita in base al tipo 'd' o ',d' formattazione specificatore è influenzato dall'uso (o non uso) di setlocale(). Tuttavia lo specificatore 'd'è interessato se si utilizzano invece le funzioni locale.format() o locale.format_string().

+3

-1 Sfortunatamente questo è ** rotto **; perpetua la legacyness del modulo locale - ** non funziona correttamente con unicode **. Prova 'format (1234, u" n ")' in una localizzazione (ad esempio francese, russo) dove il separatore delle migliaia è uno SPAZIO NO-BREAK. Si ottiene l'eccezione preferita dei principianti: 'UnicodeDecodeError: il codec 'ascii' non può decodificare il byte 0xa0 ...' –

+1

@John Machin: Per la cronaca, la maggior parte degli upvotes sono stati apportati a questa risposta prima di aggiungere la nota sull'utilizzo 'locale' - e per l'illuminazione di tutti, solo che cosa * è * il motivo attualmente corretto per l'operazione in un modo specifico della locale che gestirà Unicode? Grazie. – martineau

+0

(1) Quando sono stati fatti i upvotes è di che rilevanza ?? (2) Non esiste l'illuminazione supportata da Python-2.X, solo un kludge: 'format (1234," n "). Decode (locale.getpreferredencoding())' :-( –

13

locale.format()

Non dimenticare di impostare il locale in modo appropriato prima.

+0

E non dimenticare di specificare un valore 'True' per l'argomento _grouping_ facoltativo, come in' locale.format (u '% d', 1234, True) 'per esempio. Apparentemente 'locale' non è completamente inetto nel gestire Unicode (come suggeriscono i commenti di @John Machin in un'altra risposta). – martineau

10

stripping dal 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 

ci sono altre soluzioni here.

+0

+1 nonostante la docstring, sembra che gestisca i numeri in virgola mobile e interi. L'uso dei nomi delle variabili "dollari" e "centesimi", oltre ad essere un po 'troppo incentrati sull'applicazione, sembra supportare questa ipotesi. La versione di Very Python portable, come presentata, tornerà alla versione 2.3, e se l'iteratore 'enumerate()' è stato sostituito con qualcosa di equivalente, fino alla versione 2.0. – martineau

+1

Per Python 2.4+, 'str (dollars) [:: - 1]' potrebbe essere sostituito con il 'readed reverse (str (dollars))'. – martineau

+0

@martineau bella recensione, io uso questa funzione su Google App Engine dove Python è limitato alla versione 2.5 fuori dalla scatola. – systempuntoout

4

Utilizzare locale.format() sul numero intero, ma fare attenzione alle impostazioni internazionali correnti sul proprio ambiente. Alcuni ambienti potrebbero non avere questo set o impostare qualcosa che non ti darà un risultato virgola.

Ecco un codice che ho dovuto scrivere per risolvere questo problema. Sarà impostato automaticamente le impostazioni internazionali per voi a seconda della piattaforma:

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)