Domanda

Sto cercando di stampare un numero intero in Pitone 2.6.1 con virgole come separatori delle migliaia.Ad esempio, voglio mostrare il numero 1234567 COME 1,234,567.Come potrei farlo?Ho visto molti esempi su Google, ma sto cercando il modo più semplice e pratico.

Non è necessario che sia specifico della locale per decidere tra punti e virgole.Preferirei qualcosa di quanto più semplice possibile.

È stato utile?

Soluzione

Impostazioni locali non consapevoli

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

Impostazioni locali

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

Riferimento

Per Mini-lingua per le specifiche del formato ,

  

L'opzione ',' segnala l'uso di una virgola per un separatore delle migliaia. Per un separatore con riconoscimento locale, utilizzare invece il 'n' tipo di presentazione intero

Altri suggerimenti

L'ho fatto funzionare:

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

Certo, non hai bisogno del supporto per l'internazionalizzazione, ma è chiaro, conciso e utilizza una libreria integrata.

P.S. Quel & Quot;% d & Quot; è il solito formattatore in stile%. Puoi avere un solo formattatore, ma può essere quello che ti serve in termini di larghezza del campo e impostazioni di precisione.

P.P.S. Se non riesci a far funzionare locale, ti suggerirei una versione modificata della risposta di 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 ricorsione è utile per il caso negativo, ma una ricorsione per virgola mi sembra un po 'eccessiva.

Per inefficienza e illeggibilità è difficile da battere:

>>> 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('-,','-')

Ecco il codice di raggruppamento delle impostazioni locali dopo aver rimosso parti non pertinenti e averlo pulito un po ':

(Quanto segue funziona solo per numeri interi)

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'

Ci sono già alcune buone risposte qui. Voglio solo aggiungere questo per riferimento futuro. In Python 2.7 ci sarà un identificatore di formato per migliaia di separatori. Secondo python docs funziona così

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

In python3.1 puoi fare la stessa cosa in questo modo:

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

Sono sorpreso che nessuno abbia menzionato che puoi farlo con f-string in Python 3.6 così semplice:

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

... dove la parte dopo i due punti è l'identificatore del formato. La virgola è il carattere separatore che desideri, quindi f"{num:_d}" utilizza i trattini bassi anziché una virgola.

Ciò equivale a utilizzare format(num, ",d") per le versioni precedenti di Python 3.

Ecco una sostituzione regex di una riga:

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

Funziona solo per output inegral:

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'

O per i float con meno di 4 cifre, modificare l'identificatore di formato su %.3f:

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

NB: non funziona correttamente con più di tre cifre decimali poiché tenterà di raggruppare la parte decimale:

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

Come funziona

Analizziamolo:

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

Questo è quello che faccio per i float.Anche se, onestamente, non sono sicuro per quali versioni funzioni, sto usando la 2.7:

my_number = 4385893.382939491

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

Ritorna:4.385.893,38

Aggiornamento:Recentemente ho avuto un problema con questo formato (non saprei dirti il ​​motivo esatto), ma sono riuscito a risolverlo rilasciando il pulsante 0:

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

Puoi anche usare '{:n}'.format( value ) per una rappresentazione locale. Penso che questo sia il modo più semplice per una soluzione di localizzazione.

Per ulteriori informazioni, cercare thousands in Python DOC .

Per la valuta, puoi utilizzare locale.currency, impostando la bandiera grouping:

Codice

import locale

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

Output

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

Sono sicuro che ci deve essere una funzione di libreria standard per questo, ma è stato divertente provare a scriverlo da solo usando la ricorsione, quindi ecco cosa mi è venuto in mente:

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)

Detto questo, se qualcun altro trova un modo standard per farlo, dovresti usarlo invece.

Dai commenti ricetta activestate 498181 Ho rielaborato questo:

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

Utilizza la funzione delle espressioni regolari: lookahead ie (?=\d) per assicurarsi che solo i gruppi di tre cifre che hanno una cifra "dopo" ottengano una virgola. Dico "after" perché la stringa è inversa a questo punto.

[::-1] inverte solo una stringa.

Espandendo leggermente la risposta di Ian Schneider:

Se si desidera utilizzare un separatore di migliaia personalizzato, la soluzione più semplice è:

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

Esempi

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

Se vuoi la rappresentazione tedesca in questo modo, diventa un po 'più complicata:

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

Python 3

-

Numeri interi (senza decimali):

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

-

Float (con decimale):

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

dove il numero prima di f specifica il numero di cifre decimali.

-

Bonus

Funzione di avvio rapido e sporco per il sistema di numerazione di lakh / crores indiani (12,34.567):

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

La risposta accettata va bene, ma in realtà preferisco format(number,','). Più facile per me interpretare e ricordare.

https://docs.python.org/3/library/functions. html # formato

da Python versione 2.6 puoi farlo:

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

Per le versioni di Python < 2.6 e solo per tua informazione, qui ci sono 2 soluzioni manuali, trasformano i float in in ma i numeri negativi funzionano correttamente:

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)

alcune cose da notare qui:

  • questa riga: stringa = '% d'% numero converte magnificamente un numero in una stringa, supporta i negativi e rilascia le frazioni dai float, rendendoli ints;
  • questa sezione indici [:: - 3] restituisce ogni terzo elemento a partire da alla fine, quindi ho usato un'altra sezione [1:] per rimuovere l'ultimo elemento perché non ho bisogno di una virgola dopo l'ultimo numero;
  • questo condizionale se l [index]! = '-' viene utilizzato per supportare numeri negativi, non inserire una virgola dopo il segno meno.

E una versione più 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)

Eccone uno che funziona anche per i float:

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

Esempio di utilizzo:

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

Un liner per Python 2.5+ e Python 3 (solo int positivo):

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

Sono un principiante di Python, ma un programmatore esperto. Ho Python 3.5, quindi posso semplicemente usare la virgola, ma questo è comunque un esercizio di programmazione interessante. Considera il caso di un numero intero senza segno. Il programma Python più leggibile per l'aggiunta di migliaia di separatori sembra essere:

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)

È anche possibile utilizzare una comprensione dell'elenco:

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)

Questo è più corto, e potrebbe essere una fodera, ma dovrai fare un po 'di ginnastica mentale per capire perché funziona. In entrambi i casi otteniamo:

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 prima versione è la scelta più sensata, se si desidera comprendere il programma.

questo è cotto in pitone per PEP - > https://www.python.org/dev/peps/pep-0378/

usa solo il formato (1000, ', d') per mostrare un numero intero con separatore delle migliaia

ci sono più formati descritti nel PEP, ce l'hanno

Questo fa soldi insieme alle virgole

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)

Ho una versione Python 2 e Python 3 di questo codice. So che è stata posta la domanda per python 2 ma ora (8 anni dopo lol) le persone probabilmente useranno python 3.

Codice 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))        


Codice Python 2: (Modifica. Il codice Python 2 non funziona. Sto pensando che la sintassi sia diversa).

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) 

Sto usando Python 2.5, quindi non ho accesso alla formattazione integrata.

Ho guardato l'intcomma del codice Django (intcomma_recurs nel codice sotto) e mi sono reso conto che è inefficiente, perché è ricorsivo e anche compilare il regex ad ogni corsa non è una buona cosa. Questo non è necessario un "problema" in quanto il django non è realmente così concentrato su questo tipo di performance di basso livello. Inoltre, mi aspettavo un fattore 10 di differenza nelle prestazioni, ma è solo 3 volte più lento.

Per curiosità ho implementato alcune versioni di intcomma per vedere quali sono i vantaggi prestazionali quando si usa regex. I miei dati di test concludono un leggero vantaggio per questo compito, ma sorprendentemente non molto.

Sono stato anche contento di vedere quello che sospettavo: l'uso dell'approccio xrange inverso non è necessario nel caso no-regex, ma rende il codice leggermente migliore al costo di circa il 10% delle prestazioni.

Suppongo inoltre che ciò che stai passando sia una stringa e assomigli in qualche modo a un numero. Risultati indeterminati altrimenti.

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

Ed ecco i risultati del 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

Numeri italiani: il separatore delle migliaia è un '.'

L'ho risolto in questo modo ... per un dittonary

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 debiti per TFR sono pari a 13.255 & # 8364 ;. l & # 8217; attivo circolante & # 232; di 195.443 euro. il fondo rischi ed oneri ha un importo pari a 13.374 euro. i debiti sono 180.947 & # 8364 ;. i tassi e risconti attivi sono pari a 2.271 euro. i ratei e risconti passivi sono pari a 1.864 euro. I crediti verso i soci sono pari a 17.630 euro.

Ecco un'altra variante che utilizza una funzione di generatore che funziona per numeri interi:

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)]))

Ed ecco 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

Solo sottoclasse long (o float o qualsiasi altra cosa). Questo è molto pratico, perché in questo modo puoi ancora usare i tuoi numeri in operazioni matematiche (e quindi il codice esistente), ma verranno tutti stampati bene nel tuo terminale.

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

Preferisco la soluzione basata su locale per progetti reali, ma penso che l'approccio con l'uso dell'assegnazione delle sezioni dovrebbe essere menzionato qui:

def format_money(f, delimiter=',', frac_digits=2):

    negative_fix = int(f < 0)

    s = '%.*f' % (frac_digits, f)
    if len(s) < 5 + frac_digits + negative_fix:
        return s

    l = list(s)
    l_fix = l[negative_fix:]
    p = len(l_fix) - frac_digits - 5
    l_fix[p::-3] = [i + delimiter for i in l_fix[p::-3]]

    return ''.join(l[:negative_fix] + l_fix)

Gist with doctests è qui - https://gist.github.com/ei-grad / b290dc761ae253af69438bbb94d82683

Per i float:

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

Per ints:

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

Se non si desidera dipendere da alcuna libreria esterna:

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

Funziona solo con numeri interi non negativi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top