Question

J'essaie d'imprimer un entier dans Python 2.6.1 avec des virgules comme séparateur de milliers. Par exemple, je souhaite afficher le numéro 1234567 sous la forme 1,234,567. Comment pourrais-je m'y prendre? J'ai vu de nombreux exemples sur Google, mais je recherche la méthode la plus simple.

Il n'est pas nécessaire que les paramètres soient définis par les paramètres régionaux et les virgules. Je préférerais quelque chose d'aussi simple que raisonnablement possible.

Était-ce utile?

La solution

Paramètres régionaux non conscients

'{:,}'.format(value)  # For Python ≥2.7
f'{value:,}'  # For Python ≥3.7

Prise en compte des paramètres régionaux

import locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')  # Customize

'{:n}'.format(value)  # For Python ≥2.7
f'{value:n}'  # For Python ≥3.7

Référence

Per Mini-langage de spécification de format ,

  

L'option ',' signale l'utilisation d'une virgule pour un séparateur de milliers. Pour un séparateur sensible aux paramètres régionaux, utilisez plutôt le type de présentation 'n' entier.

Autres conseils

J'ai ce que ça fonctionne:

>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'en_US')
'en_US'
>>> locale.format("%d", 1255000, grouping=True)
'1,255,000'

Bien sûr, vous n'avez pas besoin de support de l'internationalisation, mais il est clair, concis et utilise une bibliothèque intégrée.

P.S. Ce & Quot;% d & Quot; est le formateur habituel de style%. Vous ne pouvez avoir qu'un seul formateur, mais vous pouvez avoir tout ce dont vous avez besoin en termes de largeur de champ et de paramètres de précision.

P.P.S. Si vous ne pouvez pas obtenir le fonctionnement locale, je suggérerais une version modifiée de la réponse de Mark:

def intWithCommas(x):
    if type(x) not in [type(0), type(0L)]:
        raise TypeError("Parameter must be an integer.")
    if x < 0:
        return '-' + intWithCommas(-x)
    result = ''
    while x >= 1000:
        x, r = divmod(x, 1000)
        result = ",%03d%s" % (r, result)
    return "%d%s" % (x, result)

La récursion est utile dans le cas négatif, mais une récursion par virgule me semble un peu excessive.

Pour l'inefficacité et l'illisibilité, difficile à battre:

>>> import itertools
>>> s = '-1234567'
>>> ','.join(["%s%s%s" % (x[0], x[1] or '', x[2] or '') for x in itertools.izip_longest(s[::-1][::3], s[::-1][1::3], s[::-1][2::3])])[::-1].replace('-,','-')

Voici le code de regroupement de paramètres régionaux après avoir supprimé et nettoyé un peu les éléments non pertinents:

(Ce qui suit ne fonctionne que pour les entiers)

def group(number):
    s = '%d' % number
    groups = []
    while s and s[-1].isdigit():
        groups.append(s[-3:])
        s = s[:-3]
    return s + ','.join(reversed(groups))

>>> group(-23432432434.34)
'-23,432,432,434'

Il y a déjà de bonnes réponses ici. Je veux juste ajouter ceci pour référence future. En python 2.7, il y aura un spécificateur de format pour le séparateur de milliers. Selon python docs ça marche comme ça

>>> '{:20,.2f}'.format(f)
'18,446,744,073,709,551,616.00'

En python3.1, vous pouvez faire la même chose comme ceci:

>>> format(1234567, ',d')
'1,234,567'

Je suis surpris que personne n'ait dit que vous pouviez le faire avec des chaînes de caractères en Python 3.6 aussi simple que cela:

>>> num = 10000000
>>> print(f"{num:,d}")
10,000,000

... où la partie après les deux points est le spécificateur de format. La virgule est le caractère de séparation souhaité. f"{num:_d}" utilise donc les traits de soulignement au lieu d’une virgule.

Cela équivaut à utiliser format(num, ",d") pour les anciennes versions de python 3.

Voici un remplacement d'une expression régulière sur une ligne:

re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1,", "%d" % val)

Ne fonctionne que pour les sorties intégrales:

import re
val = 1234567890
re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1,", "%d" % val)
# Returns: '1,234,567,890'

val = 1234567890.1234567890
# Returns: '1,234,567,890'

Ou pour les flottants de moins de 4 chiffres, définissez le spécificateur de format sur %.3f:

re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1,", "%.3f" % val)
# Returns: '1,234,567,890.123'

NB: ne fonctionne pas correctement avec plus de trois chiffres décimaux car il tentera de regrouper la partie décimale:

re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1,", "%.5f" % val)
# Returns: '1,234,567,890.12,346'

Comment ça marche

Décomposons:

re.sub(pattern, repl, string)

pattern = \
    "(\d)           # Find one digit...
     (?=            # that is followed by...
         (\d{3})+   # one or more groups of three digits...
         (?!\d)     # which are not followed by any more digits.
     )",

repl = \
    r"\1,",         # Replace that one digit by itself, followed by a comma,
                    # and continue looking for more matches later in the string.
                    # (re.sub() replaces all matches it finds in the input)

string = \
    "%d" % val      # Format the string as a decimal to begin with

C’est ce que je fais pour les flotteurs. Honnêtement, bien que je ne sois pas sûr de la version pour laquelle cela fonctionne, j’utilise 2.7:

my_number = 4385893.382939491

my_string = '{:0,.2f}'.format(my_number)

Retours: 4 385 893,38

Mise à jour: j'ai récemment eu un problème avec ce format (je ne pouvais pas vous dire la raison exacte), mais j'ai pu le résoudre en supprimant le 0:

my_string = '{:,.2f}'.format(my_number)

Vous pouvez également utiliser '{:n}'.format( value ) pour une représentation des paramètres régionaux. Je pense que c’est le moyen le plus simple pour une solution de localisation.

Pour plus d'informations, recherchez thousands dans DOC Python .

Pour les devises, vous pouvez utiliser locale.currency, en définissant le drapeau grouping:

Code

import locale

locale.setlocale( locale.LC_ALL, '' )
locale.currency( 1234567.89, grouping = True )

Sortie

'Portuguese_Brazil.1252'
'R$ 1.234.567,89'

Je suis sûr qu'il doit y avoir une fonction de bibliothèque standard pour cela, mais c'était amusant d'essayer de l'écrire moi-même en utilisant la récursivité, donc voici ce que j'ai créé:

def intToStringWithCommas(x):
    if type(x) is not int and type(x) is not long:
        raise TypeError("Not an integer!")
    if x < 0:
        return '-' + intToStringWithCommas(-x)
    elif x < 1000:
        return str(x)
    else:
        return intToStringWithCommas(x / 1000) + ',' + '%03d' % (x % 1000)

Cela dit, si quelqu'un trouve un moyen standard de le faire, vous devriez l'utiliser à la place.

Extrait du commentaires 498181 J'ai retravaillé ceci:

import re
def thous(x, sep=',', dot='.'):
    num, _, frac = str(x).partition(dot)
    num = re.sub(r'(\d{3})(?=\d)', r'\1'+sep, num[::-1])[::-1]
    if frac:
        num += dot + frac
    return num

Il utilise la fonctionnalité des expressions régulières: lookahead , c.-à-d. (?=\d) Assurez-vous que seuls les groupes de trois chiffres qui ont un chiffre «après» reçoivent une virgule. Je dis «après» car la chaîne est inversée à ce stade.

[::-1] inverse simplement une chaîne.

Légèrement élargi la réponse de Ian Schneider:

Si vous souhaitez utiliser un séparateur de milliers personnalisé, la solution la plus simple est la suivante:

'{:,}'.format(value).replace(',', your_custom_thousands_separator)

Exemples

'{:,.2f}'.format(123456789.012345).replace(',', ' ')

Si vous voulez que la représentation allemande ressemble à ceci, cela devient un peu plus compliqué:

('{:,.2f}'.format(123456789.012345)
          .replace(',', ' ')  # 'save' the thousands separators 
          .replace('.', ',')  # dot to comma
          .replace(' ', '.')) # thousand separators to dot

Python 3

-

Entiers (sans décimale):

"{:,d}".format(1234567)

-

Flotteurs (avec décimales):

"{:,.2f}".format(1234567)

où le nombre précédant f indique le nombre de décimales.

-

Bonus

Fonction de démarrage rapide pour le système de numérotation indien lakhs / crores (12,34,567):

https://stackoverflow.com/a/44832241/4928578

La réponse acceptée convient, mais je préfère réellement format(number,','). Plus facile pour moi d'interpréter et de me souvenir.

https://docs.python.org/3/library/functions. # format HTML

à partir de la version 2.6 de Python, vous pouvez le faire:

def format_builtin(n):
    return format(n, ',')

Pour les versions Python < 2.6 et juste pour votre information, voici 2 solutions manuelles, elles convertissent les flottants en entiers mais les nombres négatifs fonctionnent correctement:

def format_number_using_lists(number):
    string = '%d' % number
    result_list = list(string)
    indexes = range(len(string))
    for index in indexes[::-3][1:]:
        if result_list[index] != '-':
            result_list.insert(index+1, ',')
    return ''.join(result_list)

quelques points à noter ici:

  • cette ligne: string = '% d'% number convertit joliment un nombre en chaîne, il prend en charge les négatifs et supprime les fractions des flottants, ce qui les rend ints;
  • cette tranche d'index [:: - 3] renvoie chaque troisième élément à partir de la fin, alors j'ai utilisé une autre tranche [1:] pour supprimer le dernier élément parce que je n'ai pas besoin d'une virgule après le dernier chiffre;
  • cette condition si l [index]! = '-' est utilisé pour prendre en charge les nombres négatifs, n'insérez pas de virgule après le signe moins.

Et une version plus hardcore:

def format_number_using_generators_and_list_comprehensions(number):
    string = '%d' % number
    generator = reversed( 
        [
            value+',' if (index!=0 and value!='-' and index%3==0) else value
            for index,value in enumerate(reversed(string))
        ]
    )
    return ''.join(generator)

En voici un qui fonctionne aussi pour les flotteurs:

def float2comma(f):
    s = str(abs(f)) # Convert to a string
    decimalposition = s.find(".") # Look for decimal point
    if decimalposition == -1:
        decimalposition = len(s) # If no decimal, then just work from the end
    out = "" 
    for i in range(decimalposition+1, len(s)): # do the decimal
        if not (i-decimalposition-1) % 3 and i-decimalposition-1: out = out+","
        out = out+s[i]      
    if len(out):
        out = "."+out # add the decimal point if necessary
    for i in range(decimalposition-1,-1,-1): # working backwards from decimal point
        if not (decimalposition-i-1) % 3 and decimalposition-i-1: out = ","+out
        out = s[i]+out      
    if f < 0:
        out = "-"+out
    return out

Exemple d'utilisation:

>>> float2comma(10000.1111)
'10,000.111,1'
>>> float2comma(656565.122)
'656,565.122'
>>> float2comma(-656565.122)
'-656,565.122'

Une doublure pour Python 2.5+ et Python 3 (int positif uniquement):

''.join(reversed([x + (',' if i and not i % 3 else '') for i, x in enumerate(reversed(str(1234567)))]))

Je suis un débutant en Python, mais un programmeur expérimenté. J'ai Python 3.5, je peux donc utiliser la virgule, mais c’est quand même un exercice de programmation intéressant. Prenons le cas d'un entier non signé. Le programme Python le plus lisible permettant d’ajouter des séparateurs de milliers semble être:

def add_commas(instr):
    out = [instr[0]]
    for i in range(1, len(instr)):
        if (len(instr) - i) % 3 == 0:
            out.append(',')
        out.append(instr[i])
    return ''.join(out)

Il est également possible d’utiliser une liste de compréhension:

add_commas(instr):
    rng = reversed(range(1, len(instr) + (len(instr) - 1)//3 + 1))
    out = [',' if j%4 == 0 else instr[-(j - j//4)] for j in rng]
    return ''.join(out)

Ceci est plus court et pourrait être une ligne, mais vous devrez faire de la gymnastique mentale pour comprendre pourquoi cela fonctionne. Dans les deux cas, on obtient:

for i in range(1, 11):
    instr = '1234567890'[:i]
    print(instr, add_commas(instr))
1 1
12 12
123 123
1234 1,234
12345 12,345
123456 123,456
1234567 1,234,567
12345678 12,345,678
123456789 123,456,789
1234567890 1,234,567,890

La première version est le choix le plus judicieux si vous voulez que le programme soit compris.

Cela fait de l’argent avec les virgules

def format_money(money, presym='$', postsym=''):
    fmt = '%0.2f' % money
    dot = string.find(fmt, '.')
    ret = []
    if money < 0 :
        ret.append('(')
        p0 = 1
    else :
        p0 = 0
    ret.append(presym)
    p1 = (dot-p0) % 3 + p0
    while True :
        ret.append(fmt[p0:p1])
        if p1 == dot : break
        ret.append(',')
        p0 = p1
        p1 += 3
    ret.append(fmt[dot:])   # decimals
    ret.append(postsym)
    if money < 0 : ret.append(')')
    return ''.join(ret)

J'ai une version de ce code python 2 et python 3. Je sais que la question a été posée pour Python 2, mais maintenant (8 ans plus tard, lol), les gens utiliseront probablement Python 3.

Code Python 3:

import random
number = str(random.randint(1, 10000000))
comma_placement = 4
print('The original number is: {}. '.format(number))
while True:
    if len(number) % 3 == 0:
        for i in range(0, len(number) // 3 - 1):
            number = number[0:len(number) - comma_placement + 1] + ',' + number[len(number) - comma_placement + 1:]
            comma_placement = comma_placement + 4
    else:
        for i in range(0, len(number) // 3):
            number = number[0:len(number) - comma_placement + 1] + ',' + number[len(number) - comma_placement + 1:]
    break
print('The new and improved number is: {}'.format(number))        


Code Python 2: (Édition. Le code Python 2 ne fonctionne pas. Je pense que la syntaxe est différente).

import random
number = str(random.randint(1, 10000000))
comma_placement = 4
print 'The original number is: %s.' % (number)
while True:
    if len(number) % 3 == 0:
        for i in range(0, len(number) // 3 - 1):
            number = number[0:len(number) - comma_placement + 1] + ',' + number[len(number) - comma_placement + 1:]
            comma_placement = comma_placement + 4
    else:
        for i in range(0, len(number) // 3):
            number = number[0:len(number) - comma_placement + 1] + ',' + number[len(number) - comma_placement + 1:]
    break
print 'The new and improved number is: %s.' % (number) 

J'utilise python 2.5, je n'ai donc pas accès au formatage intégré.

J'ai examiné le code Django intcomma (intcomma_recurs dans le code ci-dessous) et je me suis rendu compte qu'il était inefficace, car il est récursif et la compilation de la regex à chaque exécution n'est pas une bonne chose non plus. Ce n'est pas nécessaire, car Django n'est pas vraiment concentré sur ce type de performance de bas niveau. De plus, je m'attendais à un facteur 10 de différence de performances, mais ce n'est que 3 fois plus lent.

Par curiosité, j’ai implémenté quelques versions d’intcomma pour voir quels sont les avantages en termes de performances lors de l’utilisation de regex. Mes données de test concluent à un léger avantage pour cette tâche, mais étonnamment pas grand chose du tout.

J'ai également été heureux de voir ce que je soupçonnais: l'utilisation de l'approche inverse de xrange n'est pas nécessaire dans le cas sans regex, mais elle donne au code une apparence légèrement meilleure, au prix d'environ 10% de performances.

De plus, je suppose que ce que vous transmettez est une chaîne et ressemble un peu à un nombre. Résultats indéterminés autrement.

from __future__ import with_statement
from contextlib import contextmanager
import re,time

re_first_num = re.compile(r"\d")
def intcomma_noregex(value):
    end_offset, start_digit, period = len(value),re_first_num.search(value).start(),value.rfind('.')
    if period == -1:
        period=end_offset
    segments,_from_index,leftover = [],0,(period-start_digit) % 3
    for _index in xrange(start_digit+3 if not leftover else start_digit+leftover,period,3):
        segments.append(value[_from_index:_index])
        _from_index=_index
    if not segments:
        return value
    segments.append(value[_from_index:])
    return ','.join(segments)

def intcomma_noregex_reversed(value):
    end_offset, start_digit, period = len(value),re_first_num.search(value).start(),value.rfind('.')
    if period == -1:
        period=end_offset
    _from_index,segments = end_offset,[]
    for _index in xrange(period-3,start_digit,-3):
        segments.append(value[_index:_from_index])
        _from_index=_index
    if not segments:
        return value
    segments.append(value[:_from_index])
    return ','.join(reversed(segments))

re_3digits = re.compile(r'(?<=\d)\d{3}(?!\d)')
def intcomma(value):
    segments,last_endoffset=[],len(value)
    while last_endoffset > 3:
        digit_group = re_3digits.search(value,0,last_endoffset)
        if not digit_group:
            break
        segments.append(value[digit_group.start():last_endoffset])
        last_endoffset=digit_group.start()
    if not segments:
        return value
    if last_endoffset:
        segments.append(value[:last_endoffset])
    return ','.join(reversed(segments))

def intcomma_recurs(value):
    """
    Converts an integer to a string containing commas every three digits.
    For example, 3000 becomes '3,000' and 45000 becomes '45,000'.
    """
    new = re.sub("^(-?\d+)(\d{3})", '\g<1>,\g<2>', str(value))
    if value == new:
        return new
    else:
        return intcomma(new)

@contextmanager
def timed(save_time_func):
    begin=time.time()
    try:
        yield
    finally:
        save_time_func(time.time()-begin)

def testset_xsimple(func):
    func('5')

def testset_simple(func):
    func('567')

def testset_onecomma(func):
    func('567890')

def testset_complex(func):
    func('-1234567.024')

def testset_average(func):
    func('-1234567.024')
    func('567')
    func('5674')

if __name__ == '__main__':
    print 'Test results:'
    for test_data in ('5','567','1234','1234.56','-253892.045'):
        for func in (intcomma,intcomma_noregex,intcomma_noregex_reversed,intcomma_recurs):
            print func.__name__,test_data,func(test_data)
    times=[]
    def overhead(x):
        pass
    for test_run in xrange(1,4):
        for func in (intcomma,intcomma_noregex,intcomma_noregex_reversed,intcomma_recurs,overhead):
            for testset in (testset_xsimple,testset_simple,testset_onecomma,testset_complex,testset_average):
                for x in xrange(1000): # prime the test
                    testset(func)
                with timed(lambda x:times.append(((test_run,func,testset),x))):
                    for x in xrange(50000):
                        testset(func)
    for (test_run,func,testset),_delta in times:
        print test_run,func.__name__,testset.__name__,_delta

Et voici les résultats du test:

intcomma 5 5
intcomma_noregex 5 5
intcomma_noregex_reversed 5 5
intcomma_recurs 5 5
intcomma 567 567
intcomma_noregex 567 567
intcomma_noregex_reversed 567 567
intcomma_recurs 567 567
intcomma 1234 1,234
intcomma_noregex 1234 1,234
intcomma_noregex_reversed 1234 1,234
intcomma_recurs 1234 1,234
intcomma 1234.56 1,234.56
intcomma_noregex 1234.56 1,234.56
intcomma_noregex_reversed 1234.56 1,234.56
intcomma_recurs 1234.56 1,234.56
intcomma -253892.045 -253,892.045
intcomma_noregex -253892.045 -253,892.045
intcomma_noregex_reversed -253892.045 -253,892.045
intcomma_recurs -253892.045 -253,892.045
1 intcomma testset_xsimple 0.0410001277924
1 intcomma testset_simple 0.0369999408722
1 intcomma testset_onecomma 0.213000059128
1 intcomma testset_complex 0.296000003815
1 intcomma testset_average 0.503000020981
1 intcomma_noregex testset_xsimple 0.134000062943
1 intcomma_noregex testset_simple 0.134999990463
1 intcomma_noregex testset_onecomma 0.190999984741
1 intcomma_noregex testset_complex 0.209000110626
1 intcomma_noregex testset_average 0.513000011444
1 intcomma_noregex_reversed testset_xsimple 0.124000072479
1 intcomma_noregex_reversed testset_simple 0.12700009346
1 intcomma_noregex_reversed testset_onecomma 0.230000019073
1 intcomma_noregex_reversed testset_complex 0.236999988556
1 intcomma_noregex_reversed testset_average 0.56299996376
1 intcomma_recurs testset_xsimple 0.348000049591
1 intcomma_recurs testset_simple 0.34600019455
1 intcomma_recurs testset_onecomma 0.625
1 intcomma_recurs testset_complex 0.773999929428
1 intcomma_recurs testset_average 1.6890001297
1 overhead testset_xsimple 0.0179998874664
1 overhead testset_simple 0.0190000534058
1 overhead testset_onecomma 0.0190000534058
1 overhead testset_complex 0.0190000534058
1 overhead testset_average 0.0309998989105
2 intcomma testset_xsimple 0.0360000133514
2 intcomma testset_simple 0.0369999408722
2 intcomma testset_onecomma 0.207999944687
2 intcomma testset_complex 0.302000045776
2 intcomma testset_average 0.523000001907
2 intcomma_noregex testset_xsimple 0.139999866486
2 intcomma_noregex testset_simple 0.141000032425
2 intcomma_noregex testset_onecomma 0.203999996185
2 intcomma_noregex testset_complex 0.200999975204
2 intcomma_noregex testset_average 0.523000001907
2 intcomma_noregex_reversed testset_xsimple 0.130000114441
2 intcomma_noregex_reversed testset_simple 0.129999876022
2 intcomma_noregex_reversed testset_onecomma 0.236000061035
2 intcomma_noregex_reversed testset_complex 0.241999864578
2 intcomma_noregex_reversed testset_average 0.582999944687
2 intcomma_recurs testset_xsimple 0.351000070572
2 intcomma_recurs testset_simple 0.352999925613
2 intcomma_recurs testset_onecomma 0.648999929428
2 intcomma_recurs testset_complex 0.808000087738
2 intcomma_recurs testset_average 1.81900000572
2 overhead testset_xsimple 0.0189998149872
2 overhead testset_simple 0.0189998149872
2 overhead testset_onecomma 0.0190000534058
2 overhead testset_complex 0.0179998874664
2 overhead testset_average 0.0299999713898
3 intcomma testset_xsimple 0.0360000133514
3 intcomma testset_simple 0.0360000133514
3 intcomma testset_onecomma 0.210000038147
3 intcomma testset_complex 0.305999994278
3 intcomma testset_average 0.493000030518
3 intcomma_noregex testset_xsimple 0.131999969482
3 intcomma_noregex testset_simple 0.136000156403
3 intcomma_noregex testset_onecomma 0.192999839783
3 intcomma_noregex testset_complex 0.202000141144
3 intcomma_noregex testset_average 0.509999990463
3 intcomma_noregex_reversed testset_xsimple 0.125999927521
3 intcomma_noregex_reversed testset_simple 0.126999855042
3 intcomma_noregex_reversed testset_onecomma 0.235999822617
3 intcomma_noregex_reversed testset_complex 0.243000030518
3 intcomma_noregex_reversed testset_average 0.56200003624
3 intcomma_recurs testset_xsimple 0.337000131607
3 intcomma_recurs testset_simple 0.342000007629
3 intcomma_recurs testset_onecomma 0.609999895096
3 intcomma_recurs testset_complex 0.75
3 intcomma_recurs testset_average 1.68300008774
3 overhead testset_xsimple 0.0189998149872
3 overhead testset_simple 0.018000125885
3 overhead testset_onecomma 0.018000125885
3 overhead testset_complex 0.0179998874664
3 overhead testset_average 0.0299999713898

Nombres italiens: le séparateur de milliers est un '.'

Je l'ai résolu de cette façon ... pour un dictonaire

from random import randint

voci = {
    "immobilizzazioni": randint(200000, 500000),
    "tfr": randint(10000, 25000),
    "ac": randint(150000, 200000),
    "fondo": randint(10500, 22350),
    "debiti": randint(150000, 250000),
    "ratei_attivi": randint(2000, 2500),
    "ratei_passivi": randint(1500, 2600),
    "crediti_v_soci": randint(10000, 30000)
}


testo_rnd2 = """Nell’azienda Hypermax S.p.a. di Bologna le immobilizzazioni valgono {immobilizzazioni:,} €, i debiti per TFR sono pari a {tfr:,} €, l’attivo circolante è di {ac:,} euro, il fondo rischi ed oneri ha un importo pari a {fondo:,} euro, i debiti sono {debiti:,} €, i ratei e risconti attivi sono pari a {ratei_attivi:,} euro, i ratei e risconti passivi sono pari a {ratei_passivi:,} euro. I crediti verso i soci sono pari a {crediti_v_soci:,} euro."""

print(testo_rnd2)

out: le immobilizzazioni valgono 419.168 & # 8364 ;. i débit par TFR sono pari un 13.255 & # 8364 ;. l & # 8217; attivo circolante & # 232; à partir de 195,443 euros. il a risqué sur les armes à la main à 13.374 euros. Debiti sono 180.947 & # 8364 ;. Je note que les réponses sont de 2.271 euros. Je note une réponse passive à 1,864 euro. Je crédite mes notes à 17.630 euros.

Voici une autre variante utilisant une fonction de générateur qui fonctionne pour les entiers:

def ncomma(num):
    def _helper(num):
        # assert isinstance(numstr, basestring)
        numstr = '%d' % num
        for ii, digit in enumerate(reversed(numstr)):
            if ii and ii % 3 == 0 and digit.isdigit():
                yield ','
            yield digit

    return ''.join(reversed([n for n in _helper(num)]))

Et voici un test:

>>> for i in (0, 99, 999, 9999, 999999, 1000000, -1, -111, -1111, -111111, -1000000):
...     print i, ncomma(i)
... 
0 0
99 99
999 999
9999 9,999
999999 999,999
1000000 1,000,000
-1 -1
-111 -111
-1111 -1,111
-111111 -111,111
-1000000 -1,000,000

Juste la sous-classe long (ou float, ou autre chose). Ceci est très pratique, car de cette manière, vous pouvez toujours utiliser vos numéros dans les opérations mathématiques (et donc le code existant), mais ils s’imprimeront tous parfaitement sur votre terminal.

>>> class number(long):

        def __init__(self, value):
            self = value

        def __repr__(self):
            s = str(self)
            l = [x for x in s if x in '1234567890']
            for x in reversed(range(len(s)-1)[::3]):
                l.insert(-x, ',')
            l = ''.join(l[1:])
            return ('-'+l if self < 0 else l) 

>>> number(-100000)
-100,000
>>> number(-100)
-100
>>> number(-12345)
-12,345
>>> number(928374)
928,374
>>> 345

Pour les flotteurs:

float(filter(lambda x: x!=',', '1,234.52'))
# returns 1234.52

Pour les ints:

int(filter(lambda x: x!=',', '1,234'))
# returns 1234

Si vous ne souhaitez pas dépendre de bibliothèques externes:

 s = str(1234567)
 print ','.join([s[::-1][k:k+3][::-1] for k in xrange(len(s)-1, -1, -3)])

Ceci ne fonctionne que pour les entiers non négatifs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top