ज़ीरोस को पीछे किए बिना फ़्लोटिंग फ़्लोटिंग


181

मैं एक फ़्लोट को कैसे प्रारूपित कर सकता हूं ताकि इसमें अनुगामी शून्य न हो? दूसरे शब्दों में, मैं चाहता हूं कि परिणामी स्ट्रिंग यथासंभव कम हो।

उदाहरण के लिए:

3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"

उस उदाहरण का कोई मतलब नहीं है। 3.14 == 3.140- वे एक ही फ्लोटिंग पॉइंट नंबर हैं। उस मामले के लिए 3.140000 एक ही फ्लोटिंग-पॉइंट नंबर है। शून्य पहले स्थान पर मौजूद नहीं है।
एस.लॉट

33
@ एस.लॉट - मुझे लगता है कि समस्या पीछे चल रहे शून्य के बिना फ्लोट संख्या को इंगित कर रही है, न कि दो संख्याओं के वास्तविक समतुल्य को।
पोकस्टेड

1
@ पोकस्टेड: जिस स्थिति में, कोई "शानदार" शून्य नहीं है। %0.2fऔर %0.3fबाईं ओर अंतिम संख्या उत्पन्न करने के लिए आवश्यक दो प्रारूप हैं। %0.2fदाईं ओर अंतिम दो संख्याओं का उत्पादन करने के लिए उपयोग करें ।
S.Lott

6
3.0 -> "3"अभी भी एक वैध उपयोग मामला है। print( '{:,g}'.format( X )उत्पादन के लिए मेरे लिए काम किया 3है, जहां X = 6 / 2और जब X = 5 / 2मैं का उत्पादन मिल गया 2.5के रूप में उम्मीद।
शूकरमेकर

1
पुराना सवाल है, लेकिन .. print("%s"%3.140)आपको जो चाहिए वो देता है। (मैंने नीचे एक जवाब नीचे जोड़ा ...)
drevicko

जवाबों:


178

मैं, मैं करता हूँ ('%f' % x).rstrip('0').rstrip('.')- वैज्ञानिक संकेतन, आदि आदि के बजाय निश्चित-बिंदु स्वरूपण की गारंटी देता है। हाँ, जितना चालाक और सुरुचिपूर्ण नहीं है %g, लेकिन, यह काम करता है (और मैं नहीं जानता कि %gवैज्ञानिक संकेतन का उपयोग करने के लिए कभी भी मजबूर नहीं करना चाहिए; -)।


6
इसके साथ एकमात्र समस्या '%.2f' % -0.0001आपको छोड़ देगी -0.00और आखिरकार -0
कोस

3
@ alexanderlukanin13 क्योंकि डिफ़ॉल्ट परिशुद्धता 6 है, docs.python.org/2/library/string.html देखें : 'f' Fixed point. Displays the number as a fixed-point number. The default precision is 6.आपको उपरोक्त समाधान में '% 0.7f' का उपयोग करना होगा।
derenio

3
@derenio अच्छा बिंदु :-) मैं केवल यह जोड़ सकता हूं कि ऊपर की सटीकता बढ़ाना '%0.15f'एक बुरा विचार है, क्योंकि अजीब चीजें होने लगती हैं।
एलेक्ज़ेंड्लुकनिन 13

1
यदि आप किसी अन्य स्ट्रिंग के बीच में हैं: print('In the middle {} and something else'.format('{:f}'.format(a).rstrip('0')))
दोष-सहिष्णु

1
@लेक्स मार्टेली, डबल rstripकमांड से छुटकारा पाएं । इसके बजाय बस इसका इस्तेमाल करें दोनों पट्टी ( .) और सभी अनुगामी शून्य को एक ऑपरेशन में बाद में:('%f' % x).rstrip('.0')
गेब्रियल स्टेपल्स

143

आप %gइसे प्राप्त करने के लिए उपयोग कर सकते हैं :

'%g'%(3.140)

या, अजगर 2.6 या बेहतर के लिए:

'{0:g}'.format(3.140)

से के लिये दस्तावेजformat : gकारणों (अन्य बातों के अलावा)

महत्वहीन अनुगामी शून्य [को] महत्व से हटा दिया जाता है, और दशमलव बिंदु भी हटा दिया जाता है यदि इसके बाद कोई शेष अंक नहीं हैं।


28
ओह, लगभग! कभी-कभी यह वैज्ञानिक संकेतन में फ्लोट को प्रारूपित करता है ("2.342E + 09") - क्या इसे बंद करना संभव है, यानी हमेशा सभी महत्वपूर्ण अंक दिखाते हैं?
तर्ज

5
'{0:...}'.format(value)जब आप उपयोग कर सकते हैं तो उपयोग क्यों करें format(value, '...')? अन्यथा खाली होने वाले टेम्पलेट स्ट्रिंग से प्रारूप निर्दिष्ट को पार्स करने से बचा जाता है।
मार्टिन पीटर्स

2
@MartijnPieters: प्रारूप विनिर्देशक को पार्स करने की न्यूनतम लागत अन्य ओवरहेड AFAICT द्वारा स्वाइप की जाती है; व्यवहार में, 3.6 पर मेरे स्थानीय बेंचमार्क (सही मॉडल वास्तविक कोड के लिए माइक्रोबेनमार्क के फ़ंक्शन स्कूपिंग के साथ) format(v, '2.5f')~ 10 गुना अधिक समय लेते हैं '{:2.5f}'.format(v)। यहां तक ​​कि अगर यह नहीं था, तो मैं strविधि के रूप का उपयोग करता हूं क्योंकि जब मुझे इसे मोड़ने की आवश्यकता होती है, तो इसमें अतिरिक्त मान जोड़ें, आदि, बदलने के लिए कम है। बेशक, 3.6 के रूप में हमारे पास अधिकांश उद्देश्यों के लिए एफ-स्ट्रिंग्स हैं। :-)
शैडो रेंजर

5
अजगर 3.6 में, यह करने के लिए छोटा किया जा सकता f"{var:g}"है, जहां varएक नाव चर रहा है।
TheGreatCabbage

12

सबसे आसान और शायद सबसे प्रभावी दृष्टिकोण की कोशिश करने के बारे में क्या? विधि सामान्यीकृत () सभी सही ट्रेलिंग शून्य हटाती है।

from decimal import Decimal

print (Decimal('0.001000').normalize())
# Result: 0.001

पायथन 2 और पायथन 3 में काम करता है ।

- अपडेट किया गया

@ BobStein-VisiBone के रूप में एकमात्र समस्या यह बताई गई है कि 10, 100, 1000 ... जैसे नंबर घातीय प्रतिनिधित्व में प्रदर्शित किए जाएंगे। इसके बजाय निम्नलिखित फ़ंक्शन का उपयोग करके इसे आसानी से ठीक किया जा सकता है:

from decimal import Decimal


def format_float(f):
    d = Decimal(str(f));
    return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()

2
सिवाय Decimal('10.0').normalize()हो जाता है'1E+1'
बॉब स्टीन

11

इसी तरह के कई सवालों के जवाब देखने के बाद, यह मेरे लिए सबसे अच्छा समाधान है:

def floatToString(inputValue):
    return ('%.15f' % inputValue).rstrip('0').rstrip('.')

मेरा तर्क:

%g वैज्ञानिक संकेतन से छुटकारा नहीं मिलता है।

>>> '%g' % 0.000035
'3.5e-05'

15 दशमलव स्थान अजीब व्यवहार से बचने के लिए लगता है और मेरी आवश्यकताओं के लिए बहुत सटीक है।

>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'

मैं format(inputValue, '.15f').इसके बजाय इस्तेमाल कर सकता था '%.15f' % inputValue, लेकिन यह थोड़ा धीमा (~ 30%) है।

मैं इस्तेमाल कर सकता था Decimal(inputValue).normalize(), लेकिन इसके साथ ही कुछ मुद्दे भी हैं। एक के लिए, यह एक बहुत धीमी (~ 11x) है। मैंने यह भी पाया कि हालाँकि इसमें बहुत बढ़िया परिशुद्धता है, फिर भी यह उपयोग करते समय सटीक नुकसान से ग्रस्त है normalize()

>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')

सबसे महत्वपूर्ण बात, मैं अभी भी Decimalएक से परिवर्तित floatकर रहा हूँ जिससे आप उस संख्या के अलावा किसी अन्य चीज़ के साथ समाप्त हो सकते हैं जो आप वहाँ डालते हैं। मुझे लगता है कि Decimalजब अंकगणित अंदर रहता है Decimalऔर Decimalएक स्ट्रिंग के साथ आरम्भ किया जाता है, तो यह सबसे अच्छा काम करता है ।

>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')

मुझे यकीन है कि Decimal.normalize()संदर्भ सेटिंग्स का उपयोग करके जो आवश्यक है उसे सटीक मुद्दा समायोजित किया जा सकता है, लेकिन पहले से ही धीमी गति को देखते हुए और हास्यास्पद परिशुद्धता और इस तथ्य की आवश्यकता नहीं है कि मैं अभी भी एक फ्लोट से परिवर्तित हो रहा हूं और वैसे भी सटीक खो जाएगा, मैंने नहीं किया लगता है कि यह पीछा करने लायक था।

मैं सम्भव नहीं हूँ "-0" के परिणाम से क्योंकि -0.0 एक मान्य फ़्लोटिंग पॉइंट नंबर है और यह शायद वैसे भी एक दुर्लभ घटना होगी, लेकिन जब से आपने उल्लेख किया है कि आप स्ट्रिंग परिणाम को यथासंभव कम रखना चाहते हैं, आप हमेशा बहुत कम अतिरिक्त गति लागत पर एक अतिरिक्त सशर्त का उपयोग कर सकता है।

def floatToString(inputValue):
    result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
    return '0' if result == '-0' else result

1
दुर्भाग्यवश केवल दशमलव स्थान के बाईं ओर कम से कम) अंकों के साथ पांच या अधिक अंकों के साथ काम करता है। उदाहरण के लिए floatToString(12345.6)लौटता '12345.600000000000364'है। 15 %.15fको कम संख्या में घटाना इस उदाहरण में हल करता है, लेकिन यह संख्या अधिक से अधिक घटने की आवश्यकता है क्योंकि संख्या बड़ी हो जाती है। यह संख्या के लॉग-बेस -10 के आधार पर गतिशील रूप से गणना की जा सकती है, लेकिन यह बहुत जल्दी जटिल हो जाती है।
जॉनस्पीक्स

1
उस समस्या को हल करने का एक तरीका यह हो सकता है कि पूरी संख्या की लंबाई को सीमित किया जाए (बल्कि दशमलव के बाद के अंकों के बजाय):result = ('%15f' % val).rstrip('0').rstrip('.').lstrip(' ')
टिमोथी स्मिथ

@ जॉनसन मुझे यकीन नहीं है कि यह परिहार्य है। यह फ्लोटिंग नंबरों का एक साइड इफेक्ट है जो सटीकता का प्रतिनिधित्व नहीं कर सकता है यदि बाईं ओर अधिक अंक आवश्यक हैं। मैं जो बता सकता हूं, वह संख्या जो एक स्ट्रिंग के रूप में निकलती है, वही संख्या है जो फ्लोट के रूप में जाती है, या कम से कम इसका निकटतम प्रतिनिधित्व। >>>12345.600000000000364 == 12345.6 True
पॉलीमेश

मैंने एक और उपाय लिखा ।
निट्सुमा

8

यहाँ एक समाधान है कि मेरे लिए काम किया है। यह PolyMesh द्वारा समाधान और नए वाक्यविन्यास के उपयोग का एक मिश्रण है ।.format()

for num in 3, 3., 3.0, 3.1, 3.14, 3.140:
    print('{0:.2f}'.format(num).rstrip('0').rstrip('.'))

आउटपुट :

3
3
3
3.1
3.14
3.14

केवल यह गलत है कि आपको दशमलव अंकों की एक समझदार संख्या निर्धारित करनी है। जितना अधिक आप इसे सेट करते हैं, उतने सटीक संख्याएं जो आप प्रतिनिधित्व कर सकते हैं, लेकिन यदि आप इसे बहुत अधिक करते हैं, तो यह प्रदर्शन को कम कर सकता है।
बेरिक

1
ब्यूरिक की टिप्पणी के अनुसार, यह अधिक सटीकता (जैसे 3.141) के फ़्लोट के लिए काम नहीं करता है क्योंकि .2fयह हार्ड-कोडेड है।
TrebledJ

3

आप इसे प्राप्त करने के लिए बस प्रारूप () का उपयोग कर सकते हैं:

format(3.140, '.10g') जहां 10 आप चाहते हैं परिशुद्धता है।


2
>>> str(a if a % 1 else int(a))

क्या आपका मतलब नहीं है int(a) if a % 1 else a?
बेरिक

प्रिय ब्यूरिक, आपका उत्तर नकारात्मक उत्तर देता है। a if a % 1 else int(a)सही है। प्रश्न स्ट्रिंग में आउटपुट की आवश्यकता है, इसलिए मैंने अभी जोड़ाstr
Shameem

आह, मैं अब समझ गया। a % 1सत्य है क्योंकि यह गैर-शून्य है। मैंने इसे गलत और गलत माना है a % 1 == 0
बेरिक

2

जबकि स्वरूपण की संभावना है कि अधिकांश पायथोनिक तरीका, यहां more_itertools.rstripउपकरण का उपयोग करके एक वैकल्पिक समाधान है ।

import more_itertools as mit


def fmt(num, pred=None):
    iterable = str(num)
    predicate = pred if pred is not None else lambda x: x in {".", "0"}
    return "".join(mit.rstrip(iterable, predicate))

assert fmt(3) == "3"
assert fmt(3.) == "3"
assert fmt(3.0) == "3"
assert fmt(3.1) == "3.1"
assert fmt(3.14) == "3.14"
assert fmt(3.140) == "3.14"
assert fmt(3.14000) == "3.14"
assert fmt("3,0", pred=lambda x: x in set(",0")) == "3"

संख्या को एक स्ट्रिंग में बदल दिया जाता है, जिसे अनुगामी संतुष्ट करने वाले अनुगामी वर्णों से छीन लिया जाता है। फ़ंक्शन की परिभाषाfmt की आवश्यकता नहीं है, लेकिन इसका उपयोग यहां दावे का परीक्षण करने के लिए किया जाता है, जो सभी पास करते हैं। नोट: यह स्ट्रिंग इनपुट पर काम करता है और वैकल्पिक विधेय को स्वीकार करता है।

भी, इस तृतीय-पक्ष लाइब्रेरी पर विवरण देखें more_itertools


1

यदि आप 3. और 3.0 के साथ "3.0" के रूप में रह सकते हैं, तो एक बहुत ही सरल दृष्टिकोण जो फ्लोटिंग प्रतिनिधित्व से सही-स्ट्रिप्स शून्य है:

print("%s"%3.140)

(अपवादों को इंगित करने के लिए धन्यवाद @ellimilial)


1
लेकिन print("%s"%3.0)करता है।
दीर्घवृत्त

1

QuantiPhy पैकेज का उपयोग करना एक विकल्प है। आम तौर पर क्वांटिपी का उपयोग इकाइयों और एसआई पैमाने कारकों के साथ संख्याओं के साथ काम करते समय किया जाता है, लेकिन इसमें विभिन्न प्रकार के अच्छे प्रारूपण विकल्प होते हैं।

    >>> from quantiphy import Quantity

    >>> cases = '3 3. 3.0 3.1 3.14 3.140 3.14000'.split()
    >>> for case in cases:
    ...    q = Quantity(case)
    ...    print(f'{case:>7} -> {q:p}')
          3 -> 3
         3. -> 3
        3.0 -> 3
        3.1 -> 3.1
       3.14 -> 3.14
      3.140 -> 3.14
    3.14000 -> 3.14

और यह इस स्थिति में ई-नोटेशन का उपयोग नहीं करेगा:

    >>> cases = '3.14e-9 3.14 3.14e9'.split()
    >>> for case in cases:
    ...    q = Quantity(case)
    ...    print(f'{case:>7} -> {q:,p}')
    3.14e-9 -> 0
       3.14 -> 3.14
     3.14e9 -> 3,140,000,000

एक वैकल्पिक विकल्प जिसे आप पसंद कर सकते हैं वह है एसआई पैमाने के कारकों का उपयोग करना, शायद इकाइयों के साथ।

    >>> cases = '3e-9 3.14e-9 3 3.14 3e9 3.14e9'.split()
    >>> for case in cases:
    ...    q = Quantity(case, 'm')
    ...    print(f'{case:>7} -> {q}')
       3e-9 -> 3 nm
    3.14e-9 -> 3.14 nm
          3 -> 3 m
       3.14 -> 3.14 m
        3e9 -> 3 Gm
     3.14e9 -> 3.14 Gm

0

ओपी सुपरफ्लस ज़ीरो को निकालना और परिणामस्वरूप स्ट्रिंग को यथासंभव छोटा करना चाहेगा।

मुझे लगता है कि% g घातीय स्वरूपण बहुत बड़े और बहुत छोटे मूल्यों के लिए परिणामी स्ट्रिंग को छोटा करता है। यह समस्या उन मानों के लिए आती है, जिन्हें घातीय संकेतन की आवश्यकता नहीं है, जैसे कि 128.0, जो न तो बहुत बड़ा है और न ही बहुत छोटा है।

यहां संख्याओं को शॉर्ट स्ट्रिंग्स के रूप में प्रारूपित करने का एक तरीका है जो% g घातीय संकेतन का उपयोग करता है केवल जब Decimal.normalize स्ट्रिंग्स बनाता है जो बहुत लंबा होता है। यह सबसे तेज़ समाधान नहीं हो सकता है (क्योंकि यह Decimal.normalize का उपयोग करता है)

def floatToString (inputValue, precision = 3):
    rc = str(Decimal(inputValue).normalize())
    if 'E' in rc or len(rc) > 5:
        rc = '{0:.{1}g}'.format(inputValue, precision)        
    return rc

inputs = [128.0, 32768.0, 65536, 65536 * 2, 31.5, 1.000, 10.0]

outputs = [floatToString(i) for i in inputs]

print(outputs)

# ['128', '32768', '65536', '1.31e+05', '31.5', '1', '10']


0

"{:.5g}".format(x)

मैं शून्य शून्य करने के लिए फ्लोट को प्रारूपित करने के लिए इसका उपयोग करता हूं।


3143.93 -> 3.1e + 03
j35t3r 18

0

यहाँ जवाब है:

import numpy

num1 = 3.1400
num2 = 3.000
numpy.format_float_positional(num1, 3, trim='-')
numpy.format_float_positional(num2, 3, trim='-')

आउटपुट "3.14" और "3"

trim='-' दोनों अनुगामी शून्य और दशमलव हटाता है।


-1

उदाहरण के लिए '% .99g' के लिए पर्याप्त चौड़ाई के साथ% g का उपयोग करें। यह किसी भी बड़ी संख्या के लिए नियत-बिंदु नोटेशन में प्रिंट करेगा।

संपादित करें: यह काम नहीं करता है

>>> '%.99g' % 0.0000001
'9.99999999999999954748111825886258685613938723690807819366455078125e-08'

1
.99सटीकता है, चौड़ाई नहीं; थोड़े उपयोगी लेकिन आपको इस तरह से वास्तविक परिशुद्धता निर्धारित करने की आवश्यकता नहीं है (स्वयं को रौंदने के अलावा)।
कोस

-1

आप max()इस तरह का उपयोग कर सकते हैं :

print(max(int(x), x))


1
आपको उस मामले पर विचार करना होगा जहां xनकारात्मक है। if x < 0: print(min(x), x) else : print(max(x), x)
थंडरपोनिक्स

एक उपयोगी विधि जब मैं जौंस को सख्त करना चाहता हूं। फ्लोट 1.0 को int 1 में बदलते हैं, इसलिए यह जावास्क्रिप्ट के समान ही प्रदर्शन करता है।
पिंगज़े

-3

आप उस तरह से सबसे अधिक पायथोनिक तरीके से इसे प्राप्त कर सकते हैं:

python3:

"{:0.0f}".format(num)

आप सही हे। सबसे आसान तरीका "{: g}" है। प्रारूप (संख्या)
Pyglouthon

-4

% F को संभालना और आपको लगाना चाहिए

% .2f

, जहां: .2f == .00 तैरता है।

उदाहरण:

प्रिंट "मूल्य:%। 2f"% मूल्य [उत्पाद]

उत्पादन:

कीमत: 1.50


1
यह स्पष्ट रूप से कहा गया है कि प्रश्न क्या नहीं चाहता है। नीचे करने की जरूरत है।
एपिसोड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.