স্ট্রিংটি একটি সংখ্যা (ফ্লোট) কিনা তা আমি কীভাবে পরীক্ষা করব?


1605

পাইথনের কোনও স্ট্রিংকে একটি সংখ্যা হিসাবে উপস্থাপন করা যায় কিনা তা যাচাই করার সর্বোত্তম সম্ভাব্য উপায় কোনটি?

আমার বর্তমানে এই ফাংশনটি হ'ল:

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

যা কেবল কুৎসিত এবং ধীরে ধীরে ধীরে ধীরেও জটিল নয় বলে মনে হয়। তবে আমি এর চেয়ে ভাল পদ্ধতি খুঁজে পাইনি কারণ floatমূল ফাংশনে কল করা আরও খারাপ।


61
আপনার বর্তমান সমাধান কি দোষ? এটি সংক্ষিপ্ত, দ্রুত এবং পঠনযোগ্য।
কর্নেল আতঙ্ক

5
এবং আপনাকে কেবল সত্য বা মিথ্যা ফিরিয়ে দিতে হবে না। পরিবর্তে আপনি যথাযথভাবে সংশোধিত মানটি ফিরিয়ে দিতে পারেন - উদাহরণস্বরূপ আপনি উদ্ধৃতিতে অ-সংখ্যা রাখার জন্য এটি ব্যবহার করতে পারেন।
থ্রাস্টন

7
একটি সফল রূপান্তর ক্ষেত্রে ভাসা (গুলি) এর ফলাফলটি ফেরত দেওয়া কি ভাল নয়? আপনার কাছে এখনও সাফল্যের জন্য চেক রয়েছে (ফলসটি মিথ্যা) এবং আপনি আসলে রূপান্তরটি পেয়েছেন, যা আপনি যেভাবেই চান সম্ভবত।
জিমিনিয়ন

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

7
ভাসা (গুলি) এর ফল বা কোনওটিতে ব্যর্থ হবেন না । যদি আপনি এটি x = float('0.00'); if x: use_float(x);এখন আপনার কোডটিতে একটি বাগ পেয়েছেন হিসাবে এটি ব্যবহার । সত্যিকারের মূল্যবোধগুলি হ'ল এই ফাংশনগুলি Noneপ্রথম স্থানে ফিরে আসার পরিবর্তে একটি ব্যতিক্রম বাড়ায় । আরও ভাল সমাধান হ'ল ইউটিলিটি ফাংশন এড়ানো এবং কলটি try catchযখন আপনি এটি ব্যবহার করতে চান তখন ভেসে উঠতে পারে surround
ওভ্যাঙ্গেল

উত্তর:


698

যা কেবল কুরুচিপূর্ণ এবং ধীর নয়

আমি উভয়কেই বিতর্ক করব।

একটি রেজেক্স বা অন্যান্য স্ট্রিং পার্সিংয়ের পদ্ধতিটি খারাপ এবং ধীর হবে।

আমি নিশ্চিত নই যে উপরের চেয়ে অনেক কিছুই দ্রুত হতে পারে। এটি ফাংশনটি কল করে এবং ফিরে আসে। চেষ্টা করুন / ক্যাচটি খুব বেশি ওভারহেডের পরিচয় দেয় না কারণ স্ট্যাক ফ্রেমের বিস্তৃত অনুসন্ধান ব্যতীত সবচেয়ে সাধারণ ব্যতিক্রম ধরা পড়ে।

সমস্যাটি হ'ল যে কোনও সংখ্যাগত রূপান্তর ফাংশনের দুটি ধরণের ফলাফল থাকে

  • একটি সংখ্যা, যদি নম্বরটি বৈধ হয়
  • কোনও স্থিতি কোড (উদাহরণস্বরূপ, এরনোর মাধ্যমে) বা কোনও বৈধ সংখ্যা পার্স করা যায় না তা দেখানোর জন্য ব্যতিক্রম।

সি (উদাহরণস্বরূপ) এটি বিভিন্ন উপায়ে হ্যাক করে। পাইথন এটিকে পরিষ্কার ও স্পষ্টভাবে জানিয়েছে।

আমি মনে করি এটি করার জন্য আপনার কোডটি নিখুঁত।


21
আমি মনে করি না যে কোডটি নিখুঁত (তবে আমি মনে করি এটি খুব কাছাকাছি): কেবলমাত্র অংশটিকে "পরীক্ষিত" হিসাবে দলে রাখা আরও স্বাভাবিক try, তাই আমি কোডটির return Trueএকটি elseঅনুচ্ছেদে রাখি try। এর অন্যতম কারণ হ'ল প্রশ্নের কোড সহ, যদি আমাকে এটি পর্যালোচনা করতে হয় তবে আমাকে যাচাই করতে হবে যে এই tryধারাটিতে থাকা দ্বিতীয় বিবৃতিতে কোনও মূল্যবৃদ্ধি বাড়াতে পারে না: অনুমোদিত, এর জন্য খুব বেশি সময় বা মস্তিষ্কের শক্তি প্রয়োজন হয় না, তবে কারও দরকার নেই কেন ব্যবহার করবেন?
এরিক হে লেবিগোট

4
উত্তরটি বাধ্যতামূলক বলে মনে হচ্ছে, তবে কেন আমাকে এটি বাক্সের বাইরে সরবরাহ করা হচ্ছে তা অবাক করে দেয় ... আমি এটি অনুলিপি করব এবং যেকোন ক্ষেত্রে এটি ব্যবহার করব।
ঋষি

9
কত ভয়াবহ। কেমন হয় যদি আমি পরোয়া করি না কি নম্বর হল শুধু যে এটা একটা সংখ্যা (যা কি আমাকে এখানে আনা)? 1-লাইনের পরিবর্তে IsNumeric()আমি হয় চেষ্টা / ধরা বা অন্য একটি চেষ্টা / ক্যাচ মোড়ানো দিয়ে শেষ করি। উঘ
বেসিক

6
এটি 'বাক্সের বাইরে' সরবরাহ করা হয়নি কারণ if is_number(s): x = float(x) else: // failকোডের মতো লাইনগুলির সংখ্যা একই try: x = float(x) catch TypeError: # fail। এই ইউটিলিটি ফাংশনটি সম্পূর্ণরূপে অপ্রয়োজনীয় বিমূর্ততা।
ওভ্যাঙ্গেল

12
তবে অ্যাবস্ট্রাকশন হ'ল লাইব্রেরির পুরো পয়েন্ট। একটি 'ইসনম্বার' ফাংশন (কোনও ভাষায়) থাকা প্রচুর পরিমাণে সহায়তা করে কারণ আপনি এটিকে বিবৃতিতে সোজা তৈরি করতে পারবেন এবং আরও বেশি পঠনযোগ্য এবং বজায় রাখতে সক্ষম কোড রয়েছে যা চেষ্টা - ব্লকগুলি চেষ্টা করে নির্ভর করে। এছাড়াও, যদি আপনার একাধিক শ্রেণি / মডিউলে একাধিকবার কোডটি ব্যবহার করার প্রয়োজন হয় তবে আপনি বিল্ট ইন ফাংশনটির চেয়ে কোডের আরও লাইন ব্যবহার করেছেন।
জ্যামেঙ্গুলার

1611

আপনি যদি ফ্লোটের পরিবর্তে (ইতিবাচক, স্বাক্ষরযুক্ত) পূর্ণসংখ্যার পার্সিংয়ের সন্ধান করছেন তবে আপনি isdigit()স্ট্রিং অবজেক্টের জন্য ফাংশনটি ব্যবহার করতে পারেন ।

>>> a = "03523"
>>> a.isdigit()
True
>>> b = "963spam"
>>> b.isdigit()
False

স্ট্রিং পদ্ধতি - isdigit(): Python2 , Python3

ইউনিকোড স্ট্রিংগুলিতে এমন কিছু আছে যা আমি ইউনিকোডের সাথে খুব বেশি পরিচিত না - এটি দশমিক / দশমিক


232
এটি নেতিবাচক হিসাবেও নেতিবাচক
ইন্ট্রিপিওন

22
Exponentials খুব দিয়ে ব্যর্থ: '1e3'.isdigit () -> মিথ্যা
এসএসসি

35
সংখ্যা! = ডিজিটের সময়, স্ট্রিংয়ের একটি পূর্ণসংখ্যা রয়েছে কিনা তা পরীক্ষা করার উপায় খুঁজছেন এমন ব্যক্তিরা এই প্রশ্নটি খুব ভালভাবেই হোঁচট খেতে পারেন এবং আইসডিজিট পদ্ধতির পক্ষে তাদের প্রয়োগের জন্য খুব উপযুক্ত হতে পারে।
অ্যাডাম পার্কিন

8
@ অ্যাডাম পারকিন: isdigit()এবং int()ইউনিকোড চরিত্রটির জন্য একটি পূর্ণসংখ্যা যেমন কী তা সম্পর্কে বিভিন্ন মতামত রয়েছে u'\u00b9': u'¹'.isdigit()এটি Trueকিন্তু int(u'¹')ভ্যালুএরর উত্থাপন করে।
jfs

6
+1: আইএসডিজিট () ওপি যা খুঁজছিল তা নাও হতে পারে, তবে এটি আমি যা চেয়েছিলাম ঠিক এটি। এটি এই ক্ষেত্রে নাও হতে পারে যে এই উত্তর এবং পদ্ধতিতে সমস্ত ধরণের সংখ্যা doesn'tাকা নেই, তবে এটি এখনও অত্যন্ত প্রাসঙ্গিক, এর সঠিকতা সম্পর্কে যুক্তিগুলির বিপরীতে। যদিও "সংখ্যা! = সংখ্যা," সংখ্যাটি এখনও সংখ্যার একটি উপসেট, বিশেষত এমন সংখ্যাগুলি যা ইতিবাচক, অ-নেতিবাচক এবং 1-10 বেস ব্যবহার করে। আরও, এই পদ্ধতিটি সেই ক্ষেত্রে বিশেষভাবে দরকারী এবং সংক্ষিপ্ত যেখানে আপনি স্ট্রিংয়ের একটি সংখ্যার আইডি কিনা তা যাচাই করতে চান যা প্রায়শই আমি বর্ণিত সংখ্যার সাবসেটে পড়ে।
জাস্টিন জনসন

159

টিএল; ডিআর সবচেয়ে ভাল সমাধানs.replace('.','',1).isdigit()

আমি বিভিন্ন পদ্ধতির তুলনা করে কিছু মানদণ্ড করেছি

def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

import re    
def is_number_regex(s):
    """ Returns True is string is a number. """
    if re.match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True


def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()

স্ট্রিংটি যদি একটি নম্বর না হয় তবে বাদ-ব্লকটি বেশ ধীর। তবে আরও গুরুত্বপূর্ণ বিষয় হল, চেষ্টা ব্যতীত পদ্ধতি হ'ল একমাত্র পন্থা যা বৈজ্ঞানিক স্বরলিপিগুলি সঠিকভাবে পরিচালনা করে।

funcs = [
          is_number_tryexcept, 
          is_number_regex,
          is_number_repl_isdigit
          ]

a_float = '.1234'

print('Float notation ".1234" is not supported by:')
for f in funcs:
    if not f(a_float):
        print('\t -', f.__name__)

".1234" ফ্লোট নোটেশনটি সমর্থিত নয়:
- is_number_regex

scientific1 = '1.000000e+50'
scientific2 = '1e50'


print('Scientific notation "1.000000e+50" is not supported by:')
for f in funcs:
    if not f(scientific1):
        print('\t -', f.__name__)




print('Scientific notation "1e50" is not supported by:')
for f in funcs:
    if not f(scientific2):
        print('\t -', f.__name__)

বৈজ্ঞানিক স্বরলিপি "1.000000e + 50" দ্বারা সমর্থিত নয়:
- is_number_regex
- is_number_repl_isdigit
বৈজ্ঞানিক স্বরলিপি "1e50" সমর্থিত নয়:
- is_number_regex
- is_number_repl_isdigit

সম্পাদনা: মানদণ্ডের ফলাফল

import timeit

test_cases = ['1.12345', '1.12.345', 'abc12345', '12345']
times_n = {f.__name__:[] for f in funcs}

for t in test_cases:
    for f in funcs:
        f = f.__name__
        times_n[f].append(min(timeit.Timer('%s(t)' %f, 
                      'from __main__ import %s, t' %f)
                              .repeat(repeat=3, number=1000000)))

যেখানে নিম্নলিখিত ফাংশনগুলি পরীক্ষা করা হয়েছিল

from re import match as re_match
from re import compile as re_compile

def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

def is_number_regex(s):
    """ Returns True is string is a number. """
    if re_match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True


comp = re_compile("^\d+?\.\d+?$")    

def compiled_regex(s):
    """ Returns True is string is a number. """
    if comp.match(s) is None:
        return s.isdigit()
    return True


def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()

এখানে চিত্র বর্ণনা লিখুন


14
সুন্দর চার্টের জন্য +1। আমি বেঞ্চমার্ক দেখেছি এবং গ্রাফ দেখেছি, সমস্ত টিএল; ডিআর জিনিস স্পষ্ট এবং স্বজ্ঞাত হয়ে উঠেছে।
jcchuks

আমি @ জিসিসিহুক্সের সাথে একমত: গ্রাফটি সমস্ত টিএল; ডিআর তাড়াতাড়ি পেতে অনেক সহায়তা করে। তবে আমি মনে করি একটি টিএল; ডিআর (যেমন: টিএল; ডিআর : সেরা সমাধানটি s.replace('.','',1).isdigit()) এই আনসারটির শুরুতে উপস্থিত হওয়া উচিত। যে কোনও ক্ষেত্রে এটি গ্রহণযোগ্য হওয়া উচিত। ধন্যবাদ!
সাইমন সি

10
এই পদ্ধতিটি নেতিবাচক সংখ্যাগুলি (ড্যাশগুলি) পরিচালনা করে না। আমি ভাসা পদ্ধতিটি ব্যবহার করার পক্ষে পরামর্শ দেব কারণ এটি ভুলগুলির ঝুঁকি কম এবং প্রতিবার কাজ করবে।
আরচিন

3
সবচেয়ে গুরুত্বপূর্ণ যেটি মনে করা দরকার তা হ'ল এমনকি অনুমানের পরেও কোনও ড্যাশ থাকতে পারে না, প্রতিস্থাপন-ইসডিজিট পদ্ধতিটি অ-সংখ্যাগুলির জন্য কেবলমাত্র দ্রুত (মিথ্যা ফলাফল), অন্যদিকে চেষ্টা ব্যতীত পদ্ধতি সংখ্যাগুলির জন্য দ্রুত (সত্য ফলাফল)। যদি আপনার বেশিরভাগ ইনপুট বৈধ ইনপুট হয় তবে আপনি চেষ্টা-বাদ দিয়ে সমাধান দিয়ে আরও ভাল হন!
মার্কাস ভন ব্রোডি

1
ঘৃণ্য স্বরলিপি '1.5e-9'বা নেতিবাচক উপর কাজ করে না ।
EL_DON

68

একটি ব্যতিক্রম রয়েছে যা আপনি বিবেচনায় নিতে চাইতে পারেন: স্ট্রিং 'নাএন'

যদি আপনি 'এনএএন' এর জন্য মিথ্যা ফিরিয়ে দিতে চান_এই নাম্বারটি পাইথন একটি সংখ্যা নয় এমন একটি সংখ্যার প্রতিনিধিত্ব করে (পরিচয় সম্পর্কিত বিষয়গুলি নিয়ে কথা বলে) তেমন কাজ করবে না:

>>> float('NaN')
nan

অন্যথায়, আমি এখন কোডের যে অংশটি আমি ব্যাপকভাবে ব্যবহার করি তার জন্য আপনাকে ধন্যবাদ জানানো উচিত। :)

জি


2
আসলে পাঠানো পাঠ্যটি যদি কোনও সংখ্যার প্রতিনিধিত্ব না করে তবে তার NaNপরিবর্তে (পরিবর্তে False) ভাল মান হতে পারে । এটির জন্য পরীক্ষা করা এক ধরণের ব্যথা (পাইথনের floatধরণের জন্য এটির জন্য আসলে একটি পদ্ধতির প্রয়োজন) তবে আপনি কোনও ত্রুটি তৈরি না করে গণনাতে এটি ব্যবহার করতে পারেন এবং কেবল ফলাফলটি পরীক্ষা করা দরকার।
kindall

7
আর একটি ব্যতিক্রম স্ট্রিং 'inf'। হয় infবা NaNএছাড়াও একটি উপসর্গযুক্ত করা যেতে পারে +বা -এখনও গ্রহণযোগ্য হতে পারে।
agf

4
আপনি যদি কোনও এনএএন এবং ইনফের জন্য মিথ্যা ফিরিয়ে দিতে চান তবে লাইনটি এক্স = ফ্লোট (গুলি) এ পরিবর্তন করুন; (x == x) এবং (x - 1! = x) ফেরত দিন। এটি ইনফ এবং
এনএএন

5
x-1 == xএর চেয়ে ছোট বড় ভাসমানদের জন্য সত্য inf। পাইথন ৩.২ থেকে আপনি math.isfiniteএমন নম্বরের জন্য পরীক্ষা করতে পারেন যা না এনএএন এবং অসীম নয়, বা উভয় math.isnanএবং তার math.isinfআগে পরীক্ষা করতে পারেন।
স্টিভ জেসোপ

56

এটি সম্পর্কে:

'3.14'.replace('.','',1).isdigit()

যা কেবল তখনই ফিরে আসবে যদি সেখানে এক বা না থাকে '।' অঙ্কের স্ট্রিং এ।

'3.14.5'.replace('.','',1).isdigit()

মিথ্যা ফিরে আসবে

সম্পাদনা: সবেমাত্র অন্য একটি মন্তব্য দেখেছি ... .replace(badstuff,'',maxnum_badstuff)অন্যান্য ক্ষেত্রে একটি যুক্ত করা যায়। আপনি যদি লবণের পাশ দিয়ে চলেছেন এবং নির্বিচারে মশালাগুলি না করে (রেফ: xkcd # 974 ) এটি ভাল করবে: পি


7
এটি নেতিবাচক সংখ্যার জন্য অ্যাকাউন্ট না।
মাইকেল বার্টন

5
বা এক্সপোজারগুলির সাথে সংখ্যাগুলি 1.234e56(যা এরূপ হিসাবে +1.234E+56এবং আরও বেশ কয়েকটি বৈকল্পিক হিসাবেও লিখিত হতে পারে )।
আলফে

re.match(r'^[+-]*(0[xbo])?[0-9A-Fa-f]*\.?[0-9A-Fa-f]*(E[+-]*[0-9A-Fa-f]+)$', 'str')একটি সংখ্যা নির্ধারণের জন্য আরও ভাল কাজ করা উচিত (তবে সবগুলিই নয়, আমি এটি দাবি করছি না)। আমি এটি ব্যবহার করার পরামর্শ দিচ্ছি না, প্রশ্নকারীর আসল কোডটি ব্যবহার করা আরও ভাল।
বাল্ড্রিক ক্রু

যদি আপনি এই সমাধান পছন্দ করি না, পড়া এই downvoting সামনে!
কোডিড্যাক্ট ডট কম এলোয়েসডিজ

মানুষ এটি এই স্মার্টতম সমাধান যা আমি এই ওয়েবসাইটে দেখেছি! সুন্দরভাবে সম্পন্ন মানুষ!
করম কুসাই

41

যা কেবল কুৎসিত এবং ধীরে ধীরে ধীরে ধীরেও জটিল নয় বলে মনে হয়।

এটি কিছুটা অভ্যস্ত হয়ে যেতে পারে তবে এটি করার অজগর উপায়। যেমন ইতিমধ্যে চিহ্নিত করা হয়েছে, বিকল্পগুলি আরও খারাপ। তবে জিনিসগুলি এইভাবে করার আরও একটি সুবিধা রয়েছে: বহুবর্ষ।

হাঁসের টাইপিংয়ের পেছনের কেন্দ্রীয় ধারণাটি হ'ল "যদি এটি হাঁটতে হাঁসের মতো কথা বলে তবে এটি একটি হাঁস।" আপনি যদি সিদ্ধান্ত নেন যে আপনার সাবক্লাস স্ট্রিং করা দরকার যাতে আপনি কীভাবে নির্ধারণ করতে পারেন যে কোনও কিছুকে ফ্লোটে রূপান্তর করা যায় কিনা? বা আপনি যদি অন্য কোনও বিষয় পুরোপুরি পরীক্ষা করার সিদ্ধান্ত নেন? উপরের কোডটি পরিবর্তন না করে আপনি এই জিনিসগুলি করতে পারেন।

অন্যান্য ভাষা ইন্টারফেস ব্যবহার করে এই সমস্যাগুলি সমাধান করে। কোন সমাধানটি অন্য থ্রেডের জন্য ভাল তা বিশ্লেষণটি সংরক্ষণ করব। মূল কথাটি হ'ল অজগরটি স্থিরভাবে হাঁসের টাইপিংয়ের সমীকরণের দিকে থাকে এবং আপনি যদি পাইথনে অনেক প্রোগ্রামিং করার পরিকল্পনা করেন তবে আপনাকে সম্ভবত এটির বাক্য গঠন করতে অভ্যস্ত হতে হবে (তবে এর অর্থ এই নয়) আপনি অবশ্যই এটি পছন্দ করতে হবে)।

অন্য একটি বিষয় যা আপনি বিবেচনায় নিতে চাইতে পারেন: অজগর অন্যান্য ভাষাগুলির তুলনায় ব্যতিক্রম ছুঁড়তে এবং ধরাতে বেশ দ্রুত (উদাহরণস্বরূপ নেট থেকে 30x দ্রুত)। হেক, ভাষা নিজেই অ-ব্যতিক্রমী, সাধারণ প্রোগ্রামের শর্তগুলি (প্রতিটি সময় আপনি লুপের জন্য ব্যবহার করেন) যোগাযোগের জন্য ব্যতিক্রম ছুঁড়ে দেয়। সুতরাং, আপনি কোনও উল্লেখযোগ্য সমস্যা লক্ষ্য না করা পর্যন্ত আমি এই কোডটির পারফরম্যান্স দিকগুলি সম্পর্কে খুব বেশি চিন্তা করব না।


1
পাইথন আর একটি সাধারণ জায়গা যেখানে বেসিক ফাংশনগুলির জন্য ব্যতিক্রম ব্যবহার করে সেগুলিতে hasattr()কেবল একটি getattr()কলটি একটিতে আবৃত try/except। তবুও, ব্যতিক্রম হ্যান্ডলিং স্বাভাবিক প্রবাহ নিয়ন্ত্রণের চেয়ে ধীরে ধীরে, তাই বেশিরভাগ সময় সত্য হতে চলেছে এমনটির জন্য এটি ব্যবহার করা পারফরম্যান্সের জরিমানার ফলাফল হতে পারে।
kindall

দেখে মনে হচ্ছে আপনি যদি ওয়ান-লাইনার চান তবে আপনি এসএল
বেসিক

পাইথোনিক হ'ল সস্তা ব্যতিক্রমগুলির প্রভাব সম্পর্কে এটি "অনুমতি চেয়ে ক্ষমা চাওয়া ভাল" ধারণাটিও।
হেলটনবাইকার

40

আলফে উল্লেখ করার পরে আপডেট করা হয়েছে জটিল উভয় হ্যান্ডেল হিসাবে আপনার আলাদাভাবে ভাসমান পরীক্ষা করার প্রয়োজন নেই:

def is_number(s):
    try:
        complex(s) # for int, long, float and complex
    except ValueError:
        return False

    return True

পূর্বে বলা হয়েছিল: এমন কিছু বিরল ঘটনা যা আপনার জটিল সংখ্যার জন্যও পরীক্ষা করতে হবে (উদাহরণস্বরূপ 1 + 2i), যা একটি ফ্লোট দ্বারা প্রতিনিধিত্ব করা যায় না:

def is_number(s):
    try:
        float(s) # for int, long and float
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False

    return True

14
আমি একমত নই এটি সাধারণ ব্যবহারে খুব কমই অসম্ভব, এবং আপনি যখন অপব্যবহারের 0.0001% সম্ভাবনার জন্য অতিরিক্ত ক্রিয়াকলাপের কলকে বোঝা না করে আপনি যখন এটি ব্যবহার করছেন তখন আপনি একটি ইস্পল_কম্পল_নম্বার () কল তৈরির পক্ষে আরও ভাল।
জিমিনিয়ন

3
আপনি স্টাফটি পুরোপুরি সরিয়ে ফেলতে float()পারেন এবং complex()কলটি সফল হওয়ার জন্য কেবল পরীক্ষা করতে পারেন। পার্স করা সমস্ত কিছু পার্স করা float()যায় complex()
আলফ

এই ফাংশনটি পান্ডসের NaNs এবং ইনফ মানগুলিকে সংখ্যাগত মান হিসাবে ফিরিয়ে দেবে।
ফিক্সক্সিক্সার

complex('(01989)')ফিরে আসবে (1989+0j)। তবে float('(01989)')ব্যর্থ হবে। সুতরাং আমি মনে করি ব্যবহার complexকরা ভাল ধারণা নয়।
plhn

26

এটি intব্যবহারের জন্য :

>>> "1221323".isdigit()
True

তবে floatআমাদের কিছু কৌশল প্রয়োজন ;-)। প্রতি ভাসমান সংখ্যার একটি পয়েন্ট থাকে ...

>>> "12.34".isdigit()
False
>>> "12.34".replace('.','',1).isdigit()
True
>>> "12.3.4".replace('.','',1).isdigit()
False

নেতিবাচক সংখ্যার জন্য কেবল যুক্ত করুন lstrip():

>>> '-12'.lstrip('-')
'12'

এবং এখন আমরা একটি সর্বজনীন উপায় পেতে:

>>> '-12.34'.lstrip('-').replace('.','',1).isdigit()
True
>>> '.-234'.lstrip('-').replace('.','',1).isdigit()
False

2
মত 1.234e56এবং অনুরূপ জিনিস পরিচালনা করে না । এছাড়াও, আমি কীভাবে জানতে পারি যে 99999999999999999999e99999999999999999999এটি কোনও সংখ্যা নয়। এটি বিশ্লেষণ করার চেষ্টা করে তা দ্রুত খুঁজে পাওয়া যায়।
আলফে

এটি 50 মিটার স্ট্রিংয়ের তালিকায় গৃহীত সমাধানের চেয়ে 30% ডলার এবং 5 কে স্ট্রিংয়ের তালিকায় 150% দ্রুত চলে। 👏
Zev Averbach

15

জাস্ট মিমিক সি #

সি # তে দুটি ভিন্ন ফাংশন রয়েছে যা স্কেলারের মানগুলির পার্সিং পরিচালনা করে:

  • Float.Parse ()
  • Float.TryParse ()

float.parse ():

def parse(string):
    try:
        return float(string)
    except Exception:
        throw TypeError

দ্রষ্টব্য: আপনি যদি ভাবছেন যে কেন আমি ব্যতিক্রমটি একটি টাইপ-এররারে পরিবর্তন করেছি, এখানে ডকুমেন্টেশন

float.try_parse ():

def try_parse(string, fail=None):
    try:
        return float(string)
    except Exception:
        return fail;

দ্রষ্টব্য: আপনি বুলিয়ান 'মিথ্যা' ফিরিয়ে দিতে চান না কারণ এটি এখনও একটি মান ধরণের। কোনওটিই ভাল নয় কারণ এটি ব্যর্থতা নির্দেশ করে। অবশ্যই, আপনি যদি অন্য কিছু চান তবে আপনি ব্যর্থ প্যারামিটারটি যা চান পরিবর্তন করতে পারেন।

'পার্স ()' এবং 'ট্রাই_ পার্স ()' অন্তর্ভুক্ত করতে ভাসা প্রসারিত করতে আপনাকে এই পদ্ধতিগুলি যুক্ত করতে 'ফ্লোট' শ্রেণি বানরপীচ করতে হবে।

আপনি যদি পূর্ব-বিদ্যমান ফাংশনগুলি সম্মান করতে চান তবে কোডটি এমন কিছু হওয়া উচিত:

def monkey_patch():
    if(!hasattr(float, 'parse')):
        float.parse = parse
    if(!hasattr(float, 'try_parse')):
        float.try_parse = try_parse

সাইডনোট: আমি ব্যক্তিগতভাবে এটিকে মুনি পাঞ্চিং বলতে পছন্দ করি কারণ মনে হয় যে আমি যখন ভাষাটি করি তবে আমি ওয়াইএমএমভি ব্যবহার করি না।

ব্যবহার:

float.parse('giggity') // throws TypeException
float.parse('54.3') // returns the scalar value 54.3
float.tryParse('twank') // returns None
float.tryParse('32.2') // returns the scalar value 32.2

এবং মহান সেজ পাইথোনাস হলি সি শার্পিসাসকে বলেছিলেন, "আপনি যা কিছু করতে পারেন তা আমি আরও ভাল করতে পারি; আমি আপনার চেয়ে আরও ভাল কিছু করতে পারি" "


আমি বেশিরভাগ জেএসে ইদানীং কোডিং করেছি এবং বাস্তবে এটি পরীক্ষা করিনি যাতে কিছুটা ছোটখাটো ত্রুটি হতে পারে। আপনি যদি কিছু দেখতে পান তবে আমার ভুলগুলি সংশোধন করতে দ্বিধা বোধ করবেন।
ইভান প্লেইস

জটিল সংখ্যার জন্য সমর্থন যুক্ত করতে @ ম্যাথু উইলকক্সসনের উত্তর দেখুন। স্ট্যাকওভারফ্লো . com/a/3335060/290340
ইভান প্লেইস

1
!পরিবর্তে ব্যবহার notকরা একটি ছোট্ট ত্রুটি হতে পারে, তবে আপনি অবশ্যই floatসিপিথন ইন -বিল্ট-ইন বৈশিষ্ট্যগুলি বরাদ্দ করতে পারবেন না ।
ব্ল্যাকজ্যাক

15

অ-সংখ্যাগুলির স্ট্রিংগুলির জন্য, try: except:নিয়মিত এক্সপ্রেশনগুলির চেয়ে ধীর। বৈধ সংখ্যাগুলির স্ট্রিংয়ের জন্য, রেজেক্স ধীর er সুতরাং, উপযুক্ত পদ্ধতিটি আপনার ইনপুটটির উপর নির্ভর করে।

যদি আপনি দেখতে পান যে আপনি কোনও পারফরম্যান্স বাইন্ডে রয়েছেন তবে আপনি ফাস্টফোনবার্স নামে একটি নতুন তৃতীয় পক্ষের মডিউল ব্যবহার করতে পারেন যা আইসফ্লোট নামে একটি ফাংশন সরবরাহ করে । সম্পূর্ণ প্রকাশ, আমি লেখক। আমি এর ফলাফলগুলি নীচের সময়গুলিতে অন্তর্ভুক্ত করেছি।


from __future__ import print_function
import timeit

prep_base = '''\
x = 'invalid'
y = '5402'
z = '4.754e3'
'''

prep_try_method = '''\
def is_number_try(val):
    try:
        float(val)
        return True
    except ValueError:
        return False

'''

prep_re_method = '''\
import re
float_match = re.compile(r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$').match
def is_number_re(val):
    return bool(float_match(val))

'''

fn_method = '''\
from fastnumbers import isfloat

'''

print('Try with non-number strings', timeit.timeit('is_number_try(x)',
    prep_base + prep_try_method), 'seconds')
print('Try with integer strings', timeit.timeit('is_number_try(y)',
    prep_base + prep_try_method), 'seconds')
print('Try with float strings', timeit.timeit('is_number_try(z)',
    prep_base + prep_try_method), 'seconds')
print()
print('Regex with non-number strings', timeit.timeit('is_number_re(x)',
    prep_base + prep_re_method), 'seconds')
print('Regex with integer strings', timeit.timeit('is_number_re(y)',
    prep_base + prep_re_method), 'seconds')
print('Regex with float strings', timeit.timeit('is_number_re(z)',
    prep_base + prep_re_method), 'seconds')
print()
print('fastnumbers with non-number strings', timeit.timeit('isfloat(x)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with integer strings', timeit.timeit('isfloat(y)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with float strings', timeit.timeit('isfloat(z)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print()

Try with non-number strings 2.39108395576 seconds
Try with integer strings 0.375686168671 seconds
Try with float strings 0.369210958481 seconds

Regex with non-number strings 0.748660802841 seconds
Regex with integer strings 1.02021503448 seconds
Regex with float strings 1.08564686775 seconds

fastnumbers with non-number strings 0.174362897873 seconds
fastnumbers with integer strings 0.179651021957 seconds
fastnumbers with float strings 0.20222902298 seconds

যেমন আপনি দেখতে পারেন

  • try: except: সংখ্যার ইনপুট জন্য দ্রুত ছিল কিন্তু একটি অবৈধ ইনপুট জন্য খুব ধীর
  • ইনপুটটি অবৈধ হলে রেজেক্স খুব কার্যকর
  • fastnumbers উভয় ক্ষেত্রেই জয়

আমি সংশোধন করে দাঁড়িয়েছি: - just দেখে মনে হচ্ছে না এটি এটি করছে। হয়তো নাম পছন্দ ব্যবহার prep_code_basisএবং prep_code_re_methodআমার ভুল প্রতিরোধকারী হবে।
আলফ

কমপক্ষে isfloatফাংশনের জন্য কীভাবে আপনার মডিউলটি কাজ করে তা বোঝাতে আপনার আপত্তি আছে ?
সলোমন উকো

@ সলোমনউকো এখানে স্ট্রিং চেকিং অংশের সোর্স কোডের একটি লিঙ্ক: github.com/SethMMorton/fastnumbers/blob/v1.0.0/src/… । মূলত, এটি স্ট্রিংয়ের প্রতিটি অক্ষরকে ক্রমানুসারে চলে এবং যাচাই করে যে এটি কোনও বৈধ ফ্লোটের জন্য একটি প্যাটার্ন অনুসরণ করে। যদি ইনপুটটি ইতিমধ্যে একটি সংখ্যা হয় তবে এটি কেবল দ্রুত পাইফ্লোট_চেক ব্যবহার করে ।
শেঠমোর্টন

1
এই থ্রেডের সেরা বিকল্পগুলির বিরুদ্ধে পরীক্ষিত আমি নিশ্চিত করি এই সমাধানটি এখন পর্যন্ত সবচেয়ে দ্রুততম। দ্বিতীয় দ্রুততম পদ্ধতিটি str(s).strip('-').replace('.','',1).isdigit()যা প্রায় 10x ধীর!
আলেকজান্ডার ম্যাকফার্লেন

14

আমি জানি এটি বিশেষত পুরানো তবে আমি একটি উত্তর যুক্ত করব যা আমি বিশ্বাস করি যে সর্বাধিক ভোট দেওয়া উত্তর থেকে নিখোঁজ তথ্যগুলি রয়েছে যা এটি খুঁজে পাওয়া যেকোন ব্যক্তির পক্ষে খুব মূল্যবান হতে পারে:

নীচের প্রতিটি পদ্ধতির জন্য তাদের কোনও গণনার সাথে সংযুক্ত করুন যদি আপনার কোনও ইনপুট গ্রহণযোগ্য হয়। (ধরে নিলাম আমরা 0-255 ইত্যাদির চেয়ে পূর্ণসংখ্যার ভোকাল সংজ্ঞা ব্যবহার করছি)

x.isdigit() x একটি পূর্ণসংখ্যা কিনা তা পরীক্ষা করার জন্য ভাল কাজ করে।

x.replace('-','').isdigit() এক্স নেতিবাচক কিনা তা যাচাই করার জন্য ভাল কাজ করে ((প্রথম অবস্থানে পরীক্ষা করুন)

x.replace('.','').isdigit() এক্স দশমিক কিনা তা পরীক্ষা করার জন্য ভাল কাজ করে।

x.replace(':','').isdigit() এক্স অনুপাত কিনা তা যাচাই করার জন্য ভাল কাজ করে।

x.replace('/','',1).isdigit() এক্স ভগ্নাংশ কিনা তা যাচাই করার জন্য ভাল কাজ করে।


1
যদিও ভগ্নাংশের জন্য, আপনার সম্ভবত সম্ভবত করা উচিত x.replace('/','',1).isdigit()বা অন্যথায় 4/7/2017 তারিখগুলি সংখ্যা হিসাবে ভুল ব্যাখ্যা করা হবে।
ইউসুয়ান চেন

শর্তগুলি শৃঙ্খলাবদ্ধ করার সর্বোত্তম উপায়গুলির জন্য: stackoverflow.com/q/3411771/5922329
ড্যানিয়েল ব্রাউন

13

এই উত্তরটি ধাপে ধাপে গাইড সরবরাহ করে উদাহরণটি সহ স্ট্রিংটি সনাক্ত করে:

  • ধনাত্নক পূর্ণসংখ্যা
  • ধনাত্মক / নেতিবাচক - পূর্ণসংখ্যা / ভাসা
  • সংখ্যার জন্য পরীক্ষার সময় কীভাবে "NaN" (একটি সংখ্যা নয়) স্ট্রিংগুলি বাতিল করবেন?

স্ট্রিংটি ইতিবাচক পূর্ণসংখ্যা কিনা তা পরীক্ষা করুন

str.isdigit()প্রদত্ত স্ট্রিংটি ইতিবাচক পূর্ণসংখ্য কিনা তা পরীক্ষা করতে আপনি ব্যবহার করতে পারেন ।

নমুনা ফলাফল:

# For digit
>>> '1'.isdigit()
True
>>> '1'.isalpha()
False

ধনাত্মক / নেতিবাচক হিসাবে স্ট্রিং পরীক্ষা করুন - পূর্ণসংখ্যা / ভাসা

str.isdigit()Falseস্ট্রিংটি negativeণাত্মক সংখ্যা বা একটি ভাসমান সংখ্যা হলে ফিরে আসে । উদাহরণ স্বরূপ:

# returns `False` for float
>>> '123.3'.isdigit()
False
# returns `False` for negative number
>>> '-123'.isdigit()
False

আপনি যদি নেতিবাচক পূর্ণসংখ্যার জন্যও পরীক্ষাfloat করতে চান এবং , তবে এটির জন্য এটি পরীক্ষা করতে আপনি একটি কাস্টম ফাংশন লিখতে পারেন:

def is_number(n):
    try:
        float(n)   # Type-casting the string to `float`.
                   # If string is not a valid `float`, 
                   # it'll raise `ValueError` exception
    except ValueError:
        return False
    return True

নমুনা রান:

>>> is_number('123')    # positive integer number
True

>>> is_number('123.4')  # positive float number
True

>>> is_number('-123')   # negative integer number
True

>>> is_number('-123.4') # negative `float` number
True

>>> is_number('abc')    # `False` for "some random" string
False

সংখ্যার জন্য পরীক্ষার সময় "NaN" (একটি সংখ্যা নয়) স্ট্রিংগুলি বাতিল করুন

উপরের ফাংশনগুলি True"এনএএন" (একটি সংখ্যা নয়) স্ট্রিংয়ের জন্য ফিরে আসবে কারণ পাইথনের জন্য এটি বৈধ ফ্লোট যা প্রতিনিধিত্ব করে এটি কোনও সংখ্যা নয়। উদাহরণ স্বরূপ:

>>> is_number('NaN')
True

নম্বরটি "NaN" কিনা তা পরীক্ষা করতে আপনি এই math.isnan()হিসাবে ব্যবহার করতে পারেন :

>>> import math
>>> nan_num = float('nan')

>>> math.isnan(nan_num)
True

অথবা আপনি যদি এটি পরীক্ষা করতে অতিরিক্ত লাইব্রেরি আমদানি করতে না চান তবে আপনি নিজেরাই এটি ব্যবহার করে এটির তুলনা করে চেক করতে পারেন ==। ভাসমানটিকে নিজের সাথে তুলনা করা Falseহলে পাইথন ফিরে আসে nan। উদাহরণ স্বরূপ:

# `nan_num` variable is taken from above example
>>> nan_num == nan_num
False

তাই, উপরে ফাংশন is_numberফিরে যাওয়ার আপডেট করা যাবে Falseজন্য"NaN" হিসাবে:

def is_number(n):
    is_number = True
    try:
        num = float(n)
        # check for "nan" floats
        is_number = num == num   # or use `math.isnan(num)`
    except ValueError:
        is_number = False
    return is_number

নমুনা রান:

>>> is_number('Nan')   # not a number "Nan" string
False

>>> is_number('nan')   # not a number string "nan" with all lower cased
False

>>> is_number('123')   # positive integer
True

>>> is_number('-123')  # negative integer
True

>>> is_number('-1.12') # negative `float`
True

>>> is_number('abc')   # "some random" string
False

PS: সংখ্যার ধরণের উপর নির্ভর করে প্রতিটি চেকের প্রতিটি ক্রিয়াকলাপ অতিরিক্ত ওভারহেডের সাথে আসে। is_numberআপনার প্রয়োজনীয়তার সাথে খাপ খায় এমন ফাংশনের সংস্করণ চয়ন করুন ।


12

ভাসতে কাস্ট করা এবং ভ্যালুআরর ধরা সম্ভবত সম্ভবত দ্রুততম উপায়, যেহেতু ভাসা () বিশেষত কেবল এটির জন্য বোঝানো হয়েছিল। এই অপারেশনের জন্য সুর করা না থাকার কারণে স্ট্রিং পার্সিংয়ের (রেজেক্স ইত্যাদি) অন্য যে কোনও কিছুর প্রয়োজন সম্ভবত ধীর হবে। আমার $ 0.02।


11
আপনার "2e-2"
ডলারগুলিও

8
@tzot কখনও কোনও আর্থিক মান উপস্থাপন করতে একটি ভাসা ব্যবহার করুন।
লুক

6
@ লুক: আমি আপনার সাথে পুরোপুরি একমত, যদিও আমি কখনও আর্থিক মূল্যবোধের প্রতিনিধিত্ব করতে ভাসা ব্যবহার করার পরামর্শ দিইনি; আমি কেবল বলেছি যে আর্থিক মানগুলি ভাসমান হিসাবে প্রতিনিধিত্ব করা যেতে পারে :)
tzot

11

আপনি ইউনিকোড স্ট্রিং ব্যবহার করতে পারেন, আপনার যা চান ঠিক তেমন করার একটি পদ্ধতি রয়েছে:

>>> s = u"345"
>>> s.isnumeric()
True

বা:

>>> s = "345"
>>> u = unicode(s)
>>> u.isnumeric()
True

http://www.tutorialspoint.com/python/string_isnumeric.htm

http://docs.python.org/2/howto/unicode.html


2
অ-নেতিবাচক ints জন্য এটি ঠিক আছে ;-)
andilabs

1
s.isdecimal()sস্ট্রিংটি একটি অ-নেতিবাচক পূর্ণসংখ্য কিনা তা পরীক্ষা করে । প্রত্যাখ্যান করে s.isnumeric()এমন অক্ষর অন্তর্ভুক্ত int()
jfs

9

আমি দেখতে চেয়েছিলাম কোন পদ্ধতিটি দ্রুততম। সামগ্রিকভাবে সেরা এবং সর্বাধিক ধারাবাহিক ফলাফল check_replaceফাংশন দিয়েছিল। দ্রুততম ফলাফলটি check_exceptionফাংশন দিয়েছিল, তবে কেবল সেখানে ব্যতিক্রম বরখাস্ত না হলে - এর কোডটি সর্বাধিক দক্ষ, তবে একটি ব্যতিক্রম ছোঁড়ার ওভারহেডটি বেশ বড়।

দয়া করে মনে রাখবেন যে সফল কাস্টের জন্য পরীক্ষা করা একমাত্র পদ্ধতি যা সঠিক, উদাহরণস্বরূপ, এটি এর সাথে কাজ করে check_exceptionতবে অন্য দুটি পরীক্ষামূলক ফাংশন বৈধ ভাসমানের জন্য মিথ্যা ফিরিয়ে দেবে:

huge_number = float('1e+100')

মানদণ্ডের কোডটি এখানে:

import time, re, random, string

ITERATIONS = 10000000

class Timer:    
    def __enter__(self):
        self.start = time.clock()
        return self
    def __exit__(self, *args):
        self.end = time.clock()
        self.interval = self.end - self.start

def check_regexp(x):
    return re.compile("^\d*\.?\d*$").match(x) is not None

def check_replace(x):
    return x.replace('.','',1).isdigit()

def check_exception(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

to_check = [check_regexp, check_replace, check_exception]

print('preparing data...')
good_numbers = [
    str(random.random() / random.random()) 
    for x in range(ITERATIONS)]

bad_numbers = ['.' + x for x in good_numbers]

strings = [
    ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(random.randint(1,10)))
    for x in range(ITERATIONS)]

print('running test...')
for func in to_check:
    with Timer() as t:
        for x in good_numbers:
            res = func(x)
    print('%s with good floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in bad_numbers:
            res = func(x)
    print('%s with bad floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in strings:
            res = func(x)
    print('%s with strings: %s' % (func.__name__, t.interval))

এখানে 2017 ম্যাকবুক প্রো 13-তে পাইথন 2.7.10 এর ফলাফল রয়েছে:

check_regexp with good floats: 12.688639
check_regexp with bad floats: 11.624862
check_regexp with strings: 11.349414
check_replace with good floats: 4.419841
check_replace with bad floats: 4.294909
check_replace with strings: 4.086358
check_exception with good floats: 3.276668
check_exception with bad floats: 13.843092
check_exception with strings: 15.786169

এখানে 2017 ম্যাকবুক প্রো 13-তে পাইথন 3.6.5 এর ফলাফল রয়েছে:

check_regexp with good floats: 13.472906000000009
check_regexp with bad floats: 12.977665000000016
check_regexp with strings: 12.417542999999995
check_replace with good floats: 6.011045999999993
check_replace with bad floats: 4.849356
check_replace with strings: 4.282754000000011
check_exception with good floats: 6.039081999999979
check_exception with bad floats: 9.322753000000006
check_exception with strings: 9.952595000000002

এখানে 2017 ম্যাকবুক প্রো 13-তে পাইপাইয়ের 2.7.13 এর ফলাফলগুলি রয়েছে:

check_regexp with good floats: 2.693217
check_regexp with bad floats: 2.744819
check_regexp with strings: 2.532414
check_replace with good floats: 0.604367
check_replace with bad floats: 0.538169
check_replace with strings: 0.598664
check_exception with good floats: 1.944103
check_exception with bad floats: 2.449182
check_exception with strings: 2.200056

10
আপনার অবৈধ ক্ষেত্রেও পারফরম্যান্স পরীক্ষা করা উচিত। এই সংখ্যাগুলির সাথে কোনও ব্যতিক্রম উত্থাপিত হয় না, এটি হ'ল "ধীর" অংশ।
উগো মোদা

1
@ উগোমদা আমি ২০১৩ সাল থেকে আপনার পরামর্শ নিয়েছি এবং এটি করেছি :)
রন রিটার

"দয়া করে মনে রাখবেন যে সফল কাস্টের জন্য পরীক্ষা করা একমাত্র পদ্ধতি যা সঠিক" <- এটি আসলে সত্য নয়। আমি উপরের আমার উত্তরে রেজিএক্সএক্স ব্যবহার করে আপনার পরীক্ষাটি চালিয়েছি এবং এটি আসলে রেজিপেক্সের চেয়ে দ্রুত চলে। আমি আমার উত্তর উপর ফলাফল যুক্ত করব।
ডেভিড লাজং ম্যাডিসন স্টেলার lar

ঘটনাচক্রে, একটি মজাদার পয়েন্ট হিসাবে, আপনার খারাপ সংখ্যার স্রষ্টা আসলে কিছু আইনী সংখ্যা তৈরি করতে পারে, যদিও এটি বিরল। :)
ডেভিড লাজং ম্যাডিসন স্টারার

8

সুতরাং এগুলি একসাথে রাখার জন্য, ন্যান, অনন্ত এবং জটিল সংখ্যার জন্য পরীক্ষা করা (মনে হবে এগুলি জে দ্বারা নির্দিষ্ট করা হবে, আমি নয়, 1+ 2 জ) এর ফলাফল:

def is_number(s):
    try:
        n=str(float(s))
        if n == "nan" or n=="inf" or n=="-inf" : return False
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False
    return True

এখন পর্যন্ত সেরা উত্তর। ধন্যবাদ
আনিস

6

ইনপুট নিম্নলিখিত হিসাবে হতে পারে:

a="50" b=50 c=50.1 d="50.1"


1-সাধারণ ইনপুট:

এই ফাংশন ইনপুট সব হতে পারে!

প্রদত্ত ভেরিয়েবলটি সংখ্যাযুক্ত কিনা তা সন্ধান করে। সংখ্যাযুক্ত স্ট্রিংগুলি alচ্ছিক চিহ্ন, যেকোন সংখ্যার, decচ্ছিক দশমিক অংশ এবং alচ্ছিক সূচকীয় অংশ নিয়ে গঠিত। সুতরাং + 0123.45e6 একটি বৈধ সংখ্যাযুক্ত মান। হেক্সাডেসিমাল (যেমন 0xf4c3b00c) এবং বাইনারি (উদাহরণস্বরূপ 0b10100111001) স্বরলিপি অনুমোদিত নয়।

is_numeric ফাংশন

import ast
import numbers              
def is_numeric(obj):
    if isinstance(obj, numbers.Number):
        return True
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            #if used + or - in digit :
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

পরীক্ষা:

>>> is_numeric("54")
True
>>> is_numeric("54.545")
True
>>> is_numeric("0x45")
True

is_float ফাংশন

প্রদত্ত ভেরিয়েবলটি ভাসমান কিনা তা সন্ধান করে। ভাসমান স্ট্রিংগুলি optionচ্ছিক চিহ্ন, যেকোন সংখ্যক, ...

import ast

def is_float(obj):
    if isinstance(obj, float):
        return True
    if isinstance(obj, int):
        return False
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        if not isinstance(nodes[-1].n, float):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

পরীক্ষা:

>>> is_float("5.4")
True
>>> is_float("5")
False
>>> is_float(5)
False
>>> is_float("5")
False
>>> is_float("+5.4")
True

অস্ট কি ?


2- আপনি যদি নিশ্চিত হন যে পরিবর্তনশীল সামগ্রীটি স্ট্রিং :

str.isdigit () পদ্ধতি ব্যবহার করুন

>>> a=454
>>> a.isdigit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'isdigit'
>>> a="454"
>>> a.isdigit()
True

3-সংখ্যার ইনপুট:

মান মান সনাক্ত করুন:

>>> isinstance("54", int)
False
>>> isinstance(54, int)
True
>>> 

ভাসা শনাক্ত করুন:

>>> isinstance("45.1", float)
False
>>> isinstance(45.1, float)
True

" ast" কি ?

4

আমি কিছু স্পিড টেস্ট করেছি। বলে দেয় যে যদি স্ট্রিং সম্ভবত নম্বর হওয়া উচিত চেষ্টা / ব্যতীত কৌশল দ্রুততম possible.If স্ট্রিং হয় সম্ভবত নম্বর হওয়া উচিত এবং আপনি আগ্রহী পূর্ণসংখ্যা চেক এটি কিছু পরীক্ষা (isdigit প্লাস শিরোনাম করতে worths '-')। আপনি যদি ভাসা নম্বর চেক করতে আগ্রহী হন তবে আপনাকে কোডটি বাদ দেওয়া ছাড়া / চেষ্টাটি ব্যবহার করতে হবে ।


4

আমার স্ট্রিংটি মৌলিক ধরণের (ভাসা, int, str, bool) কাস্ট করা দরকার কিনা তা নির্ধারণ করা দরকার। ইন্টারনেটে কিছু না পাওয়ার পরে আমি এটি তৈরি করেছি:

def str_to_type (s):
    """ Get possible cast type for a string

    Parameters
    ----------
    s : string

    Returns
    -------
    float,int,str,bool : type
        Depending on what it can be cast to

    """    
    try:                
        f = float(s)        
        if "." not in s:
            return int
        return float
    except ValueError:
        value = s.upper()
        if value == "TRUE" or value == "FALSE":
            return bool
        return type(s)

উদাহরণ

str_to_type("true") # bool
str_to_type("6.0") # float
str_to_type("6") # int
str_to_type("6abc") # str
str_to_type(u"6abc") # unicode       

আপনি টাইপ ক্যাপচার এবং এটি ব্যবহার করতে পারেন

s = "6.0"
type_ = str_to_type(s) # float
f = type_(s) 

3

রায়ানএন পরামর্শ দেয়

আপনি যদি কোনও এনএএন এবং ইনফের জন্য মিথ্যা ফিরিয়ে দিতে চান তবে লাইনটি এক্স = ফ্লোট (গুলি) এ পরিবর্তন করুন; (x == x) এবং (x - 1! = x) ফেরত দিন। এটি ইনফ এবং এনএএন বাদে সমস্ত ফ্লোটের ক্ষেত্রে সত্য ফিরে আসবে

তবে এটি বেশ কার্যকর নয়, কারণ পর্যাপ্ত পরিমাণে ভাসমানদের জন্য, x-1 == xসত্য ফিরে আসে। উদাহরণ স্বরূপ,2.0**54 - 1 == 2.0**54


3

আমি মনে করি আপনার সমাধান জরিমানা, কিন্তু হয় একটি সঠিক regexp বাস্তবায়ন।

এই উত্তরগুলির প্রতি প্রচুর ঘৃণাজনক ঘৃণা বলে মনে হচ্ছে যা আমি মনে করি যে এটি ন্যায়বিচারহীন, রিজেক্সপস যুক্তিসঙ্গতভাবে পরিষ্কার এবং সঠিক এবং দ্রুত হতে পারে। এটি আপনি যা করার চেষ্টা করছেন তার উপর নির্ভর করে। আসল প্রশ্নটি ছিল আপনি কীভাবে "কোনও স্ট্রিংকে একটি সংখ্যা (ফ্লোট) হিসাবে উপস্থাপন করা যায়" (আপনার শিরোনাম অনুসারে) পরীক্ষা করতে পারেন। সম্ভবত আপনি সংখ্যাসূচক / ফ্লোট মানটি ব্যবহার করতে চাইবেন একবার যাচাই হয়ে গেছে যে এটি বৈধ, যা ক্ষেত্রে আপনার চেষ্টা / ব্যতীত অনেক চেষ্টা করে। তবে যদি কোনও কারণে, আপনি কেবল সেই স্ট্রিংটি বৈধ করতে চান একটি সংখ্যাতারপরে একটি রেজেক্সও ঠিকঠাক কাজ করে তবে এটি সঠিক হওয়া শক্ত। আমি মনে করি এখন পর্যন্ত বেশিরভাগ রেইজেক্স উত্তরগুলি উদাহরণস্বরূপ, পূর্ণসংখ্যার অংশ (যেমন ".7") ব্যতীত স্ট্রিংগুলি যথাযথভাবে পার্স করবেন না যা অজগর সম্পর্কিত হিসাবে একটি ফ্লোট। এবং একক রেজিেক্সে পরীক্ষা করা সামান্য জটিল যেখানে ভগ্নাংশের অংশ প্রয়োজন হয় না। আমি এটি দেখাতে দুটি রেইজেক্স অন্তর্ভুক্ত করেছি।

এটি একটি "সংখ্যা" কী তা আকর্ষণীয় প্রশ্ন উত্থাপন করে। আপনি কি "ইনফ" অন্তর্ভুক্ত করবেন যা পাইথনে ভাসমান হিসাবে বৈধ? অথবা আপনি এমন সংখ্যার সাথে যুক্ত করেছেন যা "সংখ্যা" তবে অজগরটিতে প্রতিনিধিত্ব করা যায় না (যেমন সংখ্যাগুলি যা ভাসমান সর্বাধিকের চেয়ে বড়)।

আপনি সংখ্যাকে কীভাবে পার্স করবেন সে সম্পর্কেও অস্পষ্টতা রয়েছে। উদাহরণস্বরূপ, "--20" সম্পর্কে কী? এটি কি একটি "সংখ্যা"? এটি "20" উপস্থাপনের আইনী উপায় কি? পাইথন আপনাকে "var = --20" করতে দেয় এবং এটিকে 20 এ সেট করতে দেয় (যদিও এটি সত্য কারণ এটি এটিকে একটি এক্সপ্রেশন হিসাবে দেখায়), তবে ভাসমান ("- 20") কাজ করে না।

যাইহোক, আরও তথ্য ছাড়াই, এখানে এমন একটি রেজেক্স রয়েছে যা আমি বিশ্বাস করি যে সমস্ত অজগরকে আচ্ছাদন করে এবং অজগরগুলি পার্স করার সময় এটি ভাসমান ।

# Doesn't properly handle floats missing the integer part, such as ".7"
SIMPLE_FLOAT_REGEXP = re.compile(r'^[-+]?[0-9]+\.?[0-9]+([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           mantissa (34)
                            #                    exponent (E+56)

# Should handle all floats
FLOAT_REGEXP = re.compile(r'^[-+]?([0-9]+|[0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           OR
                            #             int/mantissa (12.34)
                            #                            exponent (E+56)

def is_float(str):
  return True if FLOAT_REGEXP.match(str) else False

কিছু উদাহরণ পরীক্ষার মান:

True  <- +42
True  <- +42.42
False <- +42.42.22
True  <- +42.42e22
True  <- +42.42E-22
False <- +42.42e-22.8
True  <- .42
False <- 42nope

@ রন-রিটারের উত্তরে বেঞ্চমার্কিং কোড চালনা দেখায় যে এই রেজেক্সটি আসলে সাধারণ রেজেক্সের তুলনায় দ্রুত এবং ব্যতিক্রমের চেয়ে খারাপ মানগুলি পরিচালনা করার ক্ষেত্রে অনেক দ্রুত, যা কিছুটা বোঝায়। ফলাফল:

check_regexp with good floats: 18.001921
check_regexp with bad floats: 17.861423
check_regexp with strings: 17.558862
check_correct_regexp with good floats: 11.04428
check_correct_regexp with bad floats: 8.71211
check_correct_regexp with strings: 8.144161
check_replace with good floats: 6.020597
check_replace with bad floats: 5.343049
check_replace with strings: 5.091642
check_exception with good floats: 5.201605
check_exception with bad floats: 23.921864
check_exception with strings: 23.755481

আশা করি এটি ঠিক - কোনও পাল্টা উদাহরণ সম্পর্কে শুনতে ভাল লাগবে। :)
ডেভিড ল্যাজুং ম্যাডিসন স্টেলার '

2
import re
def is_number(num):
    pattern = re.compile(r'^[-+]?[-0-9]\d*\.\d*|[-+]?\.?[0-9]\d*$')
    result = pattern.match(num)
    if result:
        return True
    else:
        return False


​>>>: is_number('1')
True

>>>: is_number('111')
True

>>>: is_number('11.1')
True

>>>: is_number('-11.1')
True

>>>: is_number('inf')
False

>>>: is_number('-inf')
False

2
আপনি 1e6একটি সংখ্যা প্রতিনিধিত্ব বিবেচনা করবেন না ?
মার্ক ডিকিনসন

1

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

try:
    myvar.append( float(string_to_check) )
except:
    continue

আপনি যদি স্ট্রিংয়ের সাথে একটি নম্বর হিসাবে দেখা দেয় তবে অপারেশনটি যা করতে চান তা দিয়ে Myvar.apppend প্রতিস্থাপন করুন। ধারণাটি হ'ল ফ্লোট () অপারেশনটি ব্যবহার করার চেষ্টা করা এবং স্ট্রিংটি একটি সংখ্যা কিনা তা নির্ধারণের জন্য ফেরত ত্রুটি ব্যবহার করা।


অ্যারের সাথে কিছু ভুল হতে পারে তবে দুর্ঘটনাক্রমে ব্যতিক্রমটি ট্রিগার করা এড়াতে আপনার সেই ফাংশনের সংযুক্ত অংশটি অন্য কোনও বিবৃতিতে স্থানান্তর করা উচিত।
ডারউইনসুরভিভার

1

আপনার উল্লিখিত ফাংশনটিও আমি ব্যবহার করেছি, তবে শীঘ্রই আমি লক্ষ্য করেছি যে স্ট্রিংগুলিকে "ন্যান", "ইনফ" এবং এর প্রকরণটি সংখ্যা হিসাবে বিবেচনা করা হয়। সুতরাং আমি আপনাকে আপনার ফাংশনের উন্নত সংস্করণ প্রস্তাব করছি, যা এই ধরণের ইনপুটটিতে মিথ্যা ফিরে আসবে এবং "1e3" রূপগুলি ব্যর্থ করবে না:

def is_float(text):
    try:
        float(text)
        # check for nan/infinity etc.
        if text.isalpha():
            return False
        return True
    except ValueError:
        return False

1

এই কোডটি রেজেনেক্স ব্যবহার করে এক্সপোজার, ফ্লোট এবং পূর্ণসংখ্যার পরিচালনা করে।

return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False

1

ব্যবহারকারী সহায়ক ফাংশন:

def if_ok(fn, string):
  try:
    return fn(string)
  except Exception as e:
    return None

তারপর

if_ok(int, my_str) or if_ok(float, my_str) or if_ok(complex, my_str)
is_number = lambda s: any([if_ok(fn, s) for fn in (int, float, complex)])

0

আপনি সত্য এবং মিথ্যা থেকে বেশি কার্যকর মানগুলি ফিরিয়ে একটি কার্যকর উপায়ে ব্যতিক্রম কৌশলকে সাধারণীকরণ করতে পারেন। উদাহরণস্বরূপ এই ফাংশনটি রাউন্ড স্ট্রিংয়ের উদ্ধৃতি দেয় তবে একা সংখ্যা ছেড়ে যায়। আর এর জন্য কিছু পরিবর্তনশীল সংজ্ঞা তৈরি করতে আমার দ্রুত এবং ময়লা ফিল্টারের জন্য যা প্রয়োজন ঠিক তা-ই is

import sys

def fix_quotes(s):
    try:
        float(s)
        return s
    except ValueError:
        return '"{0}"'.format(s)

for line in sys.stdin:
    input = line.split()
    print input[0], '<- c(', ','.join(fix_quotes(c) for c in input[1:]), ')'

0

আমি এমন একটি সমস্যায় কাজ করছিলাম যা আমাকে এই থ্রেডে নিয়ে গেছে, যথা কীভাবে ডেটা সংগ্রহের সর্বাধিক স্বজ্ঞাত উপায়ে স্ট্রিং এবং সংখ্যায় রূপান্তর করা যায়। মূল কোডটি পড়ার পরে আমি বুঝতে পারি যে আমার যা প্রয়োজন তা দুটি উপায়ে আলাদা ছিল:

1 - আমি একটি পূর্ণসংখ্যার ফলাফল চেয়েছিলাম যদি স্ট্রিংটি একটি পূর্ণসংখ্যার প্রতিনিধিত্ব করে

2 - আমি একটি ডেটা কাঠামোতে লেগে থাকার জন্য একটি সংখ্যা বা একটি স্ট্রিং ফলাফল চেয়েছিলাম

সুতরাং আমি এই ডেরাইভেটিভ উত্পাদন করতে মূল কোডটি অভিযোজিত করেছি:

def string_or_number(s):
    try:
        z = int(s)
        return z
    except ValueError:
        try:
            z = float(s)
            return z
        except ValueError:
            return s

0

এটা চেষ্টা কর.

 def is_number(var):
    try:
       if var == int(var):
            return True
    except Exception:
        return False

প্রতিক্রিয়া জানাতে ব্যর্থis_number('10')
ভূগোলিক

@ জিওথোরি, "সাড়া দিতে ব্যর্থ" বলতে কী বোঝ?
সলোমন উকো

0
def is_float(s):
    if s is None:
        return False

    if len(s) == 0:
        return False

    digits_count = 0
    dots_count = 0
    signs_count = 0

    for c in s:
        if '0' <= c <= '9':
            digits_count += 1
        elif c == '.':
            dots_count += 1
        elif c == '-' or c == '+':
            signs_count += 1
        else:
            return False

    if digits_count == 0:
        return False

    if dots_count > 1:
        return False

    if signs_count > 1:
        return False

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