বিন্যাস শূন্যগুলি ছাড়াই ভাসমান


180

আমি কীভাবে কোনও ফ্লোটকে ফর্ম্যাট করতে পারি যাতে এতে পিছনের জিরো না থাকে? অন্য কথায়, আমি ফলস্বরূপ স্ট্রিং যতটা সম্ভব সংক্ষিপ্ত হতে চাই।

উদাহরণ স্বরূপ:

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ডানদিকে শেষ দুটি সংখ্যা উত্পাদন করতে ব্যবহার করুন ।
এসলট

6
3.0 -> "3"এখনও একটি বৈধ ব্যবহারের কেস। যেখানে এবং কখন প্রত্যাশিত একটি আউটপুট পেয়েছিলাম print( '{:,g}'.format( X )তার জন্য আমার পক্ষে কাজ করে । 3X = 6 / 2X = 5 / 22.5
ShoeMaker

1
পুরানো প্রশ্ন, কিন্তু .. print("%s"%3.140)আপনি যা চান তা আপনাকে দেয়। (আমি নীচে নীচে একটি উত্তর যুক্ত করেছি ...)
ড্রেভিকো

উত্তর:


177

আমি, আমি করতাম ('%f' % x).rstrip('0').rstrip('.')- বৈজ্ঞানিক স্বরলিপি ইত্যাদির চেয়ে স্থির-বিন্দু বিন্যাসের গ্যারান্টি দেয় হ্যাঁ, এর মতো চতুর এবং মার্জিত %gনয়, তবে এটি কাজ করে (এবং কীভাবে %gকখনই বৈজ্ঞানিক স্বরলিপি ব্যবহার করতে বাধ্য করা যায় তা আমি জানি না ; -)।


6
এটির সাথে একমাত্র সমস্যাটি '%.2f' % -0.0001আপনাকে ছেড়ে দেবে -0.00এবং শেষ পর্যন্ত -0
কোস

3
@ অ্যালেক্সান্ডারলুকানিন ১৩ কারণ ডিফল্ট নির্ভুলতা is টি, ডকস.পিথন.আর. / / লাইবারি / স্ট্রিং এইচটিএমএল দেখুন : 'f' Fixed point. Displays the number as a fixed-point number. The default precision is 6.উপরের সমাধানটিতে আপনাকে '% 0.7f' ব্যবহার করতে হবে।
ডেরেনিও

3
@ ডেরেনিও ভাল পয়েন্ট :-) আমি কেবল যুক্ত করতে পারি যে উপরে নির্ভুলতা বাড়ানো '%0.15f'একটি খারাপ ধারণা, কারণ অদ্ভুত জিনিসগুলি ঘটতে শুরু করে।
আলেকজান্ডারলুকানিন ১৩

1
আপনি যদি অন্য কোনও স্ট্রিংয়ের মাঝখানে থাকেন: print('In the middle {} and something else'.format('{:f}'.format(a).rstrip('0')))
দোষ-সহনশীল

1
অ্যালেক্স মার্তেলি, ডাবল rstripকমান্ড থেকে মুক্তি দিন get বিন্দু ( .) এবং সমস্ত চলমান শূন্যগুলি উভয় পরে এক ('%f' % x).rstrip('.0')
গ্যাব্রিয়েল স্ট্যাপলস

143

আপনি %gএটি অর্জন করতে ব্যবহার করতে পারেন :

'%g'%(3.140)

বা, পাইথন ২.6 বা তার জন্য আরও ভাল:

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

থেকে এর জন্য দস্তাবেজformat : gকারণ (অন্যান্য বিষয় ছাড়াও)

তাত্পর্যপূর্ণ ত্রুটিযুক্ত শূন্যগুলি [তা মুছে ফেলা] থেকে মুছে ফেলা হয় এবং দশমিক বিন্দুটিও অনুসরণ করা হয় যদি এটির অনুসরণের বাকী কোনও অঙ্ক না থাকে।


28
ওহ, প্রায়! কখনও কখনও এটি বৈজ্ঞানিক স্বরলিপিতে ফ্লোটকে ("2.342E + 09") ফর্ম্যাট করে - এটি কি বন্ধ করা সম্ভব, অর্থাত্ সবসময় সমস্ত উল্লেখযোগ্য সংখ্যা দেখায়?
টারজিজেড

5
'{0:...}'.format(value)আপনি যখন ব্যবহার করতে পারেন কেন ব্যবহার করবেন format(value, '...')? এটি অন্যথায় খালি এমন কোনও টেম্পলেট স্ট্রিং থেকে ফর্ম্যাট স্পেসিফায়ারকে বিশ্লেষণ করা এড়িয়ে চলে।
মার্টিজন পিটারস

2
@ মার্তিজ্নপিটারস: ফর্ম্যাট স্পেসিফায়ারকে বিশ্লেষণের মিনিস্কুল ব্যয়টি অন্যান্য ওভারহেড এএএএফসিটি দ্বারা সজ্জিত করা হয়েছে; অনুশীলনে, আমার স্থানীয় বেঞ্চমার্কগুলিতে 3.6 (মাইক্রোবেঞ্চমার্কের ফাংশনটি সঠিকভাবে বাস্তব কোডের মডেল তৈরি করতে) এর format(v, '2.5f')চেয়ে 10% বেশি সময় নিয়েছে '{:2.5f}'.format(v)। তা না strপারলেও আমি পদ্ধতি ফর্মটি ব্যবহার করার প্রবণতা রাখি কারণ যখন আমাকে এটি টুইট করতে হবে, তখন এটিতে অতিরিক্ত মান যুক্ত করা দরকার ইত্যাদি পরিবর্তনগুলি কম হয়। অবশ্যই, 3.6 হিসাবে আমাদের বেশিরভাগ উদ্দেশ্যে এফ-স্ট্রিং রয়েছে। :-)
শ্যাডোর্যাঞ্জার

5
পাইথন ৩.6-এ, এটি ছোট করা যেতে পারে f"{var:g}"যেখানে varফ্লোট ভেরিয়েবল।
দ্য গ্রেটক্যাবেজ

12

সবচেয়ে সহজ এবং সম্ভবত সবচেয়ে কার্যকর পদ্ধতির চেষ্টা সম্পর্কে কি? পদ্ধতিটি সাধারণকরণ () সমস্ত ডানদিকের অনুসরণযোগ্য শূন্যগুলি সরিয়ে দেয়।

from decimal import Decimal

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

কাজ করে পাইথন 2 এবং পাইথন 3

- আপডেট -

@ ববস্টেইন-ভিজিবোন হিসাবে চিহ্নিত হওয়া কেবলমাত্র সমস্যাটি হ'ল 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(), তবে এটিতে কয়েকটি সমস্যাও রয়েছে। একটির জন্য, এটি একটি অনেক ধীর গতি (11 ডলার)। আমি আরও দেখতে পেয়েছি যে এটির দুর্দান্ত দুর্দান্ত নির্ভুলতা থাকলেও এটি ব্যবহারের সময় এখনও নির্ভুলতা ক্ষতিগ্রস্থ হয় 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 এর ভিত্তিতে গতিশীলভাবে গণনা করা যেতে পারে তবে এটি খুব জটিল হয়ে যায়।
জনস্পিক 3

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
ট্রাবলডজে

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
শামীম

আহ, আমি এখন এটি পেয়েছি। 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প্রয়োজন হয় না, তবে এটি এখানে পরীক্ষাগুলি পরীক্ষার জন্য ব্যবহৃত হয়, যা সমস্ত পাস করে। দ্রষ্টব্য: এটি স্ট্রিং ইনপুটগুলিতে কাজ করে এবং alচ্ছিক পূর্বাভাসগুলি গ্রহণ করে।

এই তৃতীয় পক্ষের লাইব্রেরিতে বিশদটি দেখুন more_itertools


1

আপনি যদি 3. এবং 3.0 "" 3.0 "হিসাবে উপস্থিত হয়ে বাঁচতে পারেন তবে খুব সহজ পদ্ধতির যা ভাসমান উপস্থাপনাগুলি থেকে ডান দিকের শূন্যগুলি:

print("%s"%3.140)

(ব্যতিক্রমগুলি নির্দেশ করার জন্য ধন্যবাদ @ ইলিমিলিয়াল)


1
কিন্তু print("%s"%3.0)না।
ইলিমিলিয়াল

1

কোয়ান্টিফি প্যাকেজ ব্যবহার করা একটি বিকল্প। ইউনিট এবং এসআই স্কেল ফ্যাক্টরগুলির সাথে সংখ্যার সাথে কাজ করার সময় সাধারণত কোয়ান্টিফি ব্যবহার করা হয় তবে এতে বিভিন্ন ধরণের সুন্দর সংখ্যার ফর্ম্যাটিং বিকল্প রয়েছে।

    >>> 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 এর মতো সূচকীয় স্বরলিপি প্রয়োজন হয় না, যা খুব বড় বা খুব ছোট নয়।

সংখ্যাকে সংক্ষিপ্ত স্ট্রিং হিসাবে ফর্ম্যাট করার একটি উপায় যা কেবলমাত্র ডেসিমাল.অনর্মালাইজ করে এমন স্ট্রিংগুলি তৈরি করে যেগুলি দীর্ঘ দীর্ঘ। এটি দ্রুততম সমাধান নাও হতে পারে (যেহেতু এটি ডেসিমাল.অনরমালাইজ ব্যবহার করে)

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

ভাসার জন্য আপনি এটি ব্যবহার করতে পারেন:

def format_float(num):
    return ('%i' if num == int(num) else '%s') % num

এটা পরীক্ষা করো:

>>> format_float(1.00000)
'1'
>>> format_float(1.1234567890000000000)
'1.123456789'

দশমিকের সমাধানের জন্য এখানে দেখুন: https://stackoverflow.com/a/42668598/5917543


0

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

আমি জিরোগুলি অনুসরণ করতে ভাসমানগুলির ফর্ম্যাট করতে এটি ব্যবহার করি।


3143.93 -> 3.1e + 03
j35t3r

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

যথেষ্ট পরিমাণে প্রস্থ সহ% জি ব্যবহার করুন, উদাহরণস্বরূপ '% .99 গ্রাম'। এটি কোনও যুক্তিসঙ্গত বড় সংখ্যার জন্য স্থির-পয়েন্ট স্বরলিপিতে মুদ্রণ করবে।

সম্পাদনা: এটি কাজ করে না

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

1
.99যথার্থতা, প্রস্থ নয়; কান্ড দরকারী, কিন্তু আপনি এইভাবে প্রকৃত নির্ভুলতা সেট করতে পাবেন না (এটি নিজে ছাঁটাই ছাড়া অন্য)।
কোস

-1

আপনি এটির max()মতো ব্যবহার করতে পারেন :

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


1
the xণাত্মক ক্ষেত্রে আপনাকে বিবেচনা করতে হবে । if x < 0: print(min(x), x) else : print(max(x), x)
ওয়াটু

আমি যখন জসন স্ট্রিংফাই করতে চাই তখন একটি দরকারী পদ্ধতি। 1.0 পরিবর্তন 1 টি তে ভাসা, তাই এটি জাভাস্ক্রিপ্ট হিসাবে ঠিক একই সঞ্চালন।
পিংজেজ

-3

আপনি এটি বেশিরভাগ পাইথোনিক উপায়ে এটি অর্জন করতে পারেন:

python3:

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

তুমি ঠিক বলছো. সবচেয়ে সহজ উপায় হ'ল "g: g}"। ফর্ম্যাট (
নাম্বার

-4

% F হ্যান্ডলিং করা এবং আপনার করা উচিত

% .2f

, যেখানে: .2f == .00 ভাসমান।

উদাহরণ:

"মূল্য:% .2f"% দাম [পণ্য] মুদ্রণ করুন

আউটপুট:

দাম: 1.50


1
এটি স্পষ্টভাবে বলা হয়েছে যে প্রশ্নটি চায় না। ডাউনভোট করা দরকার
এপিসিড্যাং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.