2010-10-11 1 views

Antwort

87

Niemand bisher die neue ',' Option erwähnt, die in Version 2.7 zur Format Spezifikation Mini-Sprache hinzugefügt wurde - siehe PEP 378: Format Specifier for Thousands Separator in der What's New in Python 2.7 document. Es ist einfach zu benutzen, weil Sie nicht mit locale herumspielen müssen (aber wegen der Internationalisierung begrenzt, siehe original PEP 378). Es funktioniert mit Floats, Ints und Dezimalzahlen - und all den anderen Formatierungsfunktionen, die in der Mini-Sprachspezifikation vorgesehen sind.

Verwendungsbeispiel:

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

Hinweis: Während diese neue Funktion auf jeden Fall praktisch ist, ist es eigentlich nicht alles, was viel schwieriger, das locale Modul zu verwenden, da mehrere andere vorgeschlagen haben. Der Vorteil besteht darin, dass numerische Ausgaben automatisch den richtigen Tausender-Konventionen (und anderen) folgen können, die in verschiedenen Ländern bei der Ausgabe von Dingen wie Zahlen, Daten und Zeiten verwendet werden. Es ist auch sehr einfach, die Standardeinstellungen von Ihrem Computer in Kraft zu setzen, ohne eine Reihe von Sprach- und Ländercodes zu lernen. Alles, was Sie tun müssen, ist:

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

Nachdem ich, dass Sie nur den allgemeinen 'n' Typencode für die Ausgabe Zahlen (beide integer und float) verwenden können.Wo ich bin, werden verwendet Kommas als Tausendertrennzeichen, so dass nach der Lokalisierungs-Einstellungen, wie oben gezeigt, ist es das, was passieren würde:

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

Ein großer Teil der restlichen Welt Perioden statt Kommas für diesen Zweck verwendet, so die Einstellung der Standardgebietsschema an verschiedenen Orten (oder explizit den Code für einen solchen Bereich in einem setlocale() Aufruf spezifiziert) erzeugt die folgende:

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

Ausgabe basierend auf dem 'd' oder ',d' Formatierungs Typspezifizierer ist unbeeinflusst von der Verwendung (oder Nichtgebrauch) von setlocale(). Der 'd'-Spezifizierer ist jedoch betroffen, wenn Sie stattdessen die Funktionen locale.format() oder locale.format_string() verwenden.

+3

-1 Leider ist das ** kaputt **; es verewigt die Vererbung des Gebietsschema-Moduls - ** es funktioniert nicht richtig mit Unicode **. Versuchen Sie 'format (1234, u 'n' ') in einem Gebietsschema (z. B. Französisch, Russisch), wo das Tausendertrennzeichen ein NO-BREAK SPACE ist. Sie erhalten die Lieblingsausnahme der Neulinge: 'UnicodeDecodeError: 'ascii' Codec kann Byte 0xa0 nicht decodieren ...' –

+1

@John Machin: Für die Aufzeichnung wurden die meisten upvotes zu dieser Antwort gemacht, bevor ich die Anmerkung über die Verwendung hinzufügte 'locale' - und für alle Erleuchtung, was * ist * der aktuelle Grund für die Operation in einer locale-spezifischen Weise, die Unicode behandelt? Vielen Dank. – martineau

+0

(1) Wann wurden die Upvotes erstellt? (2) Es gibt keine Python-2.X-unterstützte Erleuchtung, nur ein Kludn: 'format (1234," n "). Decode (locale.getpreferredencoding())' :-( –

13

locale.format()

Vergessen Sie nicht, in geeigneter Weise zuerst das Gebietsschema einzustellen.

+0

Und vergessen Sie nicht, einen 'True' Wert für das optionale _grouping_ Argument anzugeben, wie zB in' locale.format (u '% d', 1234, True) ''. Anscheinend ist 'locale' im Umgang mit Unicode nicht ganz unpassend (wie @John Machins Kommentare in einer anderen Antwort zu suggerieren scheinen). – martineau

10

von webpyutils.py Stripped:

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 

andere Lösungen here Es gibt keine.

+0

+1 trotz der Docstring, sieht es so aus, als ob es Fließkommazahlen sowie ganze Zahlen behandelt. Die Verwendung der Variablennamen "Dollar" und "Cents" scheint diese Hypothese zu stützen, abgesehen davon, dass sie etwas übermäßig anwendungszentriert sind. Sehr Python-Version portable, wie dargestellt, wird auf Version 2.3, und wenn der 'enumerate() 'Iterator wurde durch die etwas Entsprechenden ersetzt, den ganzen Weg zurück zu Version 2.0. – martineau

+1

Für Python 2.4+ könnte das 'str (dollars) [:: - 1]' durch das besser lesbare 'reversed (str (dollars))' ersetzt werden. – martineau

+0

@martineau netter Bericht, ich benutze diese Funktion in Google App Engine, wo Python auf Version 2.5 out of the Box beschränkt ist. – systempuntoout

4

Verwenden Sie locale.format() für die Ganzzahl, aber achten Sie auf das aktuelle Gebietsschema in Ihrer Umgebung. In einigen Umgebungen ist diese Einstellung möglicherweise nicht festgelegt oder auf etwas eingestellt, das Ihnen kein eindeutiges Ergebnis liefert.

Hier ist ein Code, den ich schreiben musste, um mit genau diesem Problem umzugehen. Es wird automatisch das Gebietsschema für Sie je nach Plattform:

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)