2010-10-11 4 views

Répondre

87

Personne n'a jusqu'à présent mentionné la nouvelle option ',' qui a été ajouté dans la version 2.7 à la Spécification du format Mini-Langue - voir PEP 378: Format Specifier for Thousands Separator dans le What's New in Python 2.7 document. Il est facile à utiliser parce que vous n'avez pas à vous tromper avec locale (mais est limité pour l'internationalisation en raison de cela, voir le original PEP 378). Il fonctionne avec des flottants, des entiers et des décimales - et toutes les autres fonctions de formatage prévues dans la spécification de mini-langage.

Exemple d'utilisation:

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

Note: Bien que cette nouvelle fonctionnalité est certainement à portée de main, il est en fait pas tout ce qui est beaucoup plus difficile à utiliser le module locale, comme plusieurs autres ont suggéré. L'avantage est que la sortie numérique peut être faite pour suivre automatiquement les milliers (et autres) conventions de séparation appropriées utilisées dans divers pays lors de la production de choses comme les nombres, les dates et les heures. Il est également très facile de mettre en œuvre les paramètres par défaut de votre ordinateur sans apprendre un tas de codes de langue et de pays. Tout ce que vous devez faire est:

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

Après avoir fait cela, vous pouvez simplement utiliser le code de type générique 'n' pour produire des nombres entiers (à la fois et float).Là où je suis, des virgules sont utilisés comme séparateur de milliers, donc après avoir réglé le lieu comme indiqué ci-dessus, voici ce qui se passerait:

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

Une grande partie du reste du monde utilise des périodes au lieu de virgules à cet effet, donc définir les paramètres régionaux par défaut dans de nombreux endroits (ou en spécifiant explicitement le code pour une région dans un appel setlocale()) produit les éléments suivants:

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

sortie sur la base du 'd' ou ',d' mise en forme spécificateur de type est pas affectée par l'utilisation (ou non-usage) de setlocale(). Cependant le 'd' spécificateur est affecté si vous utilisez à la place les fonctions locale.format() ou locale.format_string().

+3

-1 Malheureusement c'est ** cassé **; il perpétue l'héritage du module de locale - ** il ne fonctionne pas correctement avec unicode **. Essayez 'format (1234, u" n ")' dans une locale (par exemple français, russe) où le séparateur des milliers est un espace NO-BREAK. Vous obtenez l'exception favorite des débutants: 'UnicodeDecodeError: le codec 'ascii' ne peut pas décoder l'octet 0xa0 ...' –

+1

@John Machin: Pour l'anecdote, la plupart des upvotes ont été faites à cette réponse avant d'ajouter la Note sur l'utilisation 'locale' - et pour l'illumination de tout le monde, quel est le pourquoi correct de l'opération d'une manière spécifique au locale qui gérera Unicode? Merci. – martineau

+0

(1) Quand les upvotes ont été faites est de quelle pertinence ?? (2) Il n'y a pas d'illumination supportée par Python-2.X, juste un kludge: 'format (1234," n "). Decode (locale.getpreferredencoding())' :-( –

13

locale.format()

Ne pas oublier de définir les paramètres régionaux de façon appropriée en premier.

+0

Et n'oubliez pas de spécifier une valeur 'True' pour l'argument facultatif _grouping_, comme dans' locale.format (u '% d', 1234, True) 'par exemple. Apparemment, 'locale 'n'est pas complètement inepte pour gérer Unicode (comme les commentaires de John Machin dans une autre réponse semblent suggérer). – martineau

10

Stripped 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 

Il existe d'autres solutions here.

+0

+ 1 malgré la docstring, on dirait qu'il gère le nombre à virgule flottante ainsi que les nombres entiers. L'utilisation des noms de variables «dollars» et «cents», en plus d'être un peu trop axé sur les applications, semble appuyer cette hypothèse. La version très Python portable, telle que présentée, retournera à la version 2.3, et si l'itérateur 'enumerate()' a été remplacé par quelque chose d'équivalent, tout le chemin de la version 2.0. – martineau

+1

Pour Python 2.4+, le 'str (dollars) [:: - 1]' pourrait être remplacé par le plus 'readverable (str (dollars))'. – martineau

+0

@martineau bonne critique, j'utilise cette fonction sur Google App Engine où Python est limité à la version 2.5 sortie de la boîte. – systempuntoout

4

Utilisez locale.format() sur l'entier, mais prenez garde aux paramètres régionaux actuels de votre environnement. Certains environnements peuvent ne pas avoir cet ensemble ou définir quelque chose qui ne vous donnera pas un résultat commafied.

Voici un code que j'ai dû écrire pour résoudre ce problème. Il va définir automatiquement les paramètres régionaux pour vous en fonction de votre plate-forme:

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) 
Questions connexes