නූලක් අංකයක් (පාවෙන) දැයි මා පරීක්ෂා කරන්නේ කෙසේද?


1627

පයිතන් හි නූලක් අංකයක් ලෙස දැක්විය හැකිදැයි පරීක්ෂා කිරීමට හොඳම ක්‍රමය කුමක්ද?

දැනට මා සතුව ඇති කාර්යය නම්:

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

එය, කැත සහ මන්දගාමී පමණක් නොව, අවුල් සහගත බවක් පෙනේ. කෙසේ වෙතත් මම වඩා හොඳ ක්‍රමයක් සොයාගෙන නැත, මන්ද floatප්‍රධාන කාර්යයට ඇමතීම ඊටත් වඩා නරක ය.


63
ඔබගේ වර්තමාන විසඳුමේ ඇති වැරැද්ද කුමක්ද? එය කෙටි, වේගවත් හා කියවිය හැකි ය.
කර්නල් භීතිකාව

5
ඔබට සත්‍ය හෝ අසත්‍යය ආපසු ලබා දිය යුතු නැත. ඒ වෙනුවට සුදුසු පරිදි වෙනස් කළ අගය ඔබට ආපසු ලබා දිය හැකිය - නිදසුනක් ලෙස ඔබට සංඛ්‍යා නොවන මිල ගණන් උපුටා දැක්වීමට මෙය භාවිතා කළ හැකිය.
ත්‍රස්ටන්

7
සාර්ථක පරිවර්තනයකදී පාවෙන (ය) වල ප්‍රති result ල ලබා දීම වඩා හොඳ නොවේද? ඔබට තවමත් සාර්ථකත්වය සඳහා චෙක්පතක් ඇත (ප්‍රති result ලය අසත්‍යය) ඔබ සැබවින්ම පරිවර්තනය කර ඇති අතර එය ඔබට කෙසේ හෝ අවශ්‍ය වනු ඇත.
ජිමිනියන්

8
මෙම ප්‍රශ්නය වඩා පැරණි වුවත්, මට කියන්නට අවශ්‍ය වූයේ මෙය ඊඒඑෆ්පී ලෙස ලේඛනගත කර ඇති අලංකාර ක්‍රමයක් බවයි. එබැවින් බොහෝ විට මේ ආකාරයේ ගැටලුවකට හොඳම විසඳුම විය හැකිය.
thiruvenkadam

7
පාවෙන (ය) වල ප්‍රති result ලය නැවත ලබා නොදෙන්න . ඔබ x = float('0.00'); if x: use_float(x);දැන් ඔබේ කේතයේ දෝෂයක් ඇති බැවින් එය භාවිතා කරන්නේ නම් . සත්‍ය ශ්‍රිතයන් මෙම ශ්‍රිතයන් නැවත පැමිණීමට වඩා ව්‍යතිරේකයක් මතු කිරීමට හේතුවයි None. වඩා හොඳ විසඳුමක් වන්නේ උපයෝගීතා ක්‍රියාකාරිත්වය වළක්වා ගැනීම සහ try catchඔබට එය භාවිතා කිරීමට අවශ්‍ය වූ විට පාවෙන ඇමතුම වට කර ගැනීමයි .
ovangle

Answers:


707

එය, කැත සහ මන්දගාමී පමණක් නොවේ

මම දෙකම විවාද කරන්නම්.

රීජෙක්ස් හෝ වෙනත් නූල් විග්‍රහ කිරීමේ ක්‍රමයක් අවලස්සන හා මන්දගාමී වනු ඇත.

ඉහත දෙයට වඩා වැඩි යමක් වේගවත් විය හැකි බව මට විශ්වාස නැත. එය ශ්‍රිතය අමතා නැවත පැමිණේ. උත්සාහ කරන්න / අල්ලා ගන්න බොහෝ පොදු දේ හඳුන්වා දෙන්නේ නැත.

ගැටළුව වන්නේ ඕනෑම සංඛ්‍යාත්මක පරිවර්තන ශ්‍රිතයකට ප්‍රති .ල දෙකක් තිබීමයි

  • අංකයක්, අංකය වලංගු නම්
  • වලංගු අංකයක් විග්‍රහ කළ නොහැකි බව පෙන්වීමට තත්ව කේතයක් (උදා: errno හරහා) හෝ ව්‍යතිරේකය.

සී (නිදසුනක් ලෙස) මේ වටා ක්‍රම ගණනාවක් හසුරුවයි. පයිතන් එය පැහැදිලිව හා පැහැදිලිව දක්වයි.

මම හිතන්නේ මෙය සිදු කිරීම සඳහා ඔබේ කේතය පරිපූර්ණයි.


21
කේතය පරිපූර්ණ යැයි මම නොසිතමි (නමුත් එය ඉතා ආසන්න යැයි මම සිතමි): වගන්තියෙහි “පරීක්‍ෂා කරන ලද” කොටස පමණක් තැබීම වඩාත් සාමාන්‍ය දෙයකි try, එබැවින් මම return Trueඑහි elseවගන්තියකට දමමි try. එක් හේතුවක් නම්, ප්‍රශ්නයේ කේතය සමඟ, මට එය සමාලෝචනය කිරීමට සිදුවුවහොත්, tryවගන්තියේ දෙවන ප්‍රකාශයට වටිනාකම් දෝෂයක් මතු කළ නොහැකි දැයි පරීක්ෂා කර බැලිය යුතුය: ලබා දී ඇත, මේ සඳහා වැඩි කාලයක් හෝ මොළයේ බලයක් අවශ්‍ය නොවේ, නමුත් කිසිවක් අවශ්‍ය නොවන විට ඒවා භාවිතා කරන්නේ ඇයි?
එරික් ඕ ලෙබිගොට්

4
පිළිතුර බලවත් බවක් පෙනේ, නමුත් එය පිටතින් ලබා නොදෙන්නේ මන්දැයි මට කල්පනා කරයි ... මම මෙය පිටපත් කර ඕනෑම අවස්ථාවක භාවිතා කරමි.
අග්ගිස්

11
කෙතරම් භයානකද. අංකය යනු එය සංඛ්‍යාවක් පමණක් යැයි මා නොසලකන්නේ නම් (මා මෙහි ගෙන ආවේ එයයි)? 1 පේළියක් වෙනුවට IsNumeric()මම උත්සාහය / අල්ලා ගැනීම හෝ වෙනත් උත්සාහයක් / අල්ලා ගැනීමකින් අවසන් වෙමි. අහ්
මූලික

6
එය 'කොටුවෙන් පිටත' සපයා නැත, මන්ද if is_number(s): x = float(x) else: // failකේත රේඛා ගණන සමාන try: x = float(x) catch TypeError: # failවේ. මෙම උපයෝගීතා ශ්‍රිතය මුළුමනින්ම අනවශ්‍ය වියුක්තයකි.
ovangle

14
නමුත් වියුක්ත කිරීම යනු පුස්තකාලවල සමස්ත ලක්ෂ්‍යයයි. 'IsNumber' ශ්‍රිතයක් තිබීම (ඕනෑම භාෂාවකින්) විශාල මුදලකට උපකාරී වේ, මන්ද ඔබට එය ප්‍රකාශ නම් කෙලින්ම ගොඩනගා ගත හැකි අතර උත්සාහක ඇල්ලීම් කුට්ටි මත යැපෙන වඩා කියවිය හැකි සහ නඩත්තු කළ හැකි කේතයක් ඇත. තවද, ඔබට එක් පන්තියකට / මොඩියුලයකට වඩා වැඩි වාර ගණනක් කේතය භාවිතා කිරීමට අවශ්‍ය නම්, ඔබ විසින් ගොඩනඟන ලද ශ්‍රිතයකට වඩා කේත පේළි භාවිතා කර ඇත.
JamEngulfer

1623

ඔබ පාවෙන වෙනුවට විග්‍රහ කිරීමේ (ධනාත්මක, අත්සන් නොකළ) පූර්ණ සංඛ්‍යා සොයන්නේ නම්, ඔබට isdigit()ශ්‍රිතය නූල් වස්තු සඳහා භාවිතා කළ හැකිය.

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

නූල් ක්‍රම - isdigit(): පයිතන් 2 , පයිතන් 3

යුනිකෝඩ් නූල්වල ද යමක් තිබේ, එය මට යුනිකෝඩ් ගැන එතරම් හුරුපුරුදු නැත - දශම / දශම වේ


234
එය සෘණාත්මකව ද negative ණාත්මක ය
intrepion

22
On ාතීයතා සමඟ ද අසමත් වේ: '1e3'.isdigit () -> අසත්ය
ssc

36
අංකයක්!
ඇඩම් පාකින්

8
@AdamParkin: isdigit()හා int(), පූර්ණ සංඛ්යාවක් උදා දේ යුනිකෝඩ් අක්ෂර සඳහා පිළිබඳ විවිධ මත ඇත u'\u00b9': u'¹'.isdigit()වේ Trueනමුත් int(u'¹')ValueError මතු කරයි.
jfs

7
+1: isdigit () OP සොයන දේ නොවිය හැක, නමුත් එය මට අවශ්‍ය දේම වේ. මෙම පිළිතුර සහ ක්‍රමය සියලු වර්ගවල සංඛ්‍යා ආවරණය නොකරන බව පෙනෙන්නට නොතිබුණද, එහි නිරවද්‍යතාවය පිළිබඳ තර්කයට පටහැනිව එය තවමත් බෙහෙවින් අදාළ වේ. "අංකය! = ඉලක්කම්" වන අතර, ඉලක්කම් තවමත් සංඛ්‍යාවේ උප කුලකයක් වන අතර, විශේෂයෙන් ධනාත්මක, negative ණාත්මක නොවන, සහ 1-10 පදනම භාවිතා කරන්න. තව දුරටත්, මෙම ක්‍රමය විශේෂයෙන් ප්‍රයෝජනවත් වන අතර, නූලක් සංඛ්‍යාත්මක හැඳුනුම්පතක් ද නැද්ද යන්න පරීක්ෂා කිරීමට ඔබට අවශ්‍ය අවස්ථාවන් සඳහා, එය බොහෝ විට මා විස්තර කළ සංඛ්‍යා උප කුලකයට වැටේ.
ජස්ටින් ජොන්සන්

173

TL; DR හොඳම විසඳුමයි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()

රූප විස්තරය මෙහි ඇතුළත් කරන්න


15
ලස්සන ප්‍රස්ථාර සඳහා +1. මම මිණුම් ලකුණ දුටුවෙමි, ප්‍රස්ථාරය දුටුවෙමි, සියලු ටීඑල්; ඩීආර් කාරණය පැහැදිලි සහ බුද්ධිමත් විය.
jcchuks

මම @JCChuks සමඟ එකඟ වෙමි: සියලු TL; DR ඉක්මනින් ලබා ගැනීමට ප්‍රස්ථාරය බොහෝ උපකාර කරයි. නමුත් මම සිතන්නේ TL; DR (වැනි: TL; DR : හොඳම විසඳුම s.replace('.','',1).isdigit()) මෙම පිළිතුරේ ආරම්භයේදීම දිස්විය යුතුය. ඕනෑම අවස්ථාවක එය පිළිගත් එකක් විය යුතුය. ස්තූතියි!
සයිමන් සී.

10
මෙම ක්‍රමය negative ණ සංඛ්‍යා (ඉර) හසුරුවන්නේ නැත. වැරැදි වලට ඇති ඉඩකඩ අඩු බැවින් පාවෙන ක්‍රමය භාවිතා කරන ලෙස මම ඉල්ලා සිටිමි.
උර්චින්

4
සැලකිල්ලට ගත යුතු වැදගත්ම දෙය නම්, ඉරක් තිබිය නොහැකි යැයි උපකල්පනය කළත්, ප්‍රතිස්ථාපනය-ඉස්ඩිගිට් ක්‍රමය සංඛ්‍යා නොවන (ව්‍යාජ ප්‍රති come ල) සඳහා පමණක් වේගවත් වන අතර උත්සාහ කිරීම හැර ක්‍රමය සංඛ්‍යා සඳහා වේගවත් වේ (සත්‍ය ප්‍රති come ලය). ඔබගේ බොහෝ ආදානය වලංගු ආදානය නම්, උත්සාහ කිරීම හැර විසඳුම සමඟ ඔබට වඩා හොඳය!
මාකස් වොන් බ්‍රෝඩි

1
On ාතීය අංකනය වැනි '1.5e-9'හෝ නිෂේධනීය මත ක්‍රියා නොකරයි .
EL_DON

68

ඔබට සැලකිල්ලට ගත යුතු එක් ව්‍යතිරේකයක් ඇත: 'NaN' නූල

'NaN' සඳහා FALSE ආපසු ලබා දීමට ඔබට is_number අවශ්‍ය නම්, මෙම කේතය ක්‍රියා නොකරන්නේ පයිතන් එය අංකයක් නොවන සංඛ්‍යාවක් නිරූපණය කිරීම සඳහා පරිවර්තනය කරන හෙයිනි (අනන්‍යතා ගැටළු ගැන කතා කරන්න):

>>> float('NaN')
nan

එසේ නොමැතිනම්, මම දැන් පුළුල් ලෙස භාවිතා කරන කේත කැබැල්ලට සැබවින්ම ස්තූතිවන්ත විය යුතුය. :)

ජී.


2
ඇත්තටම, NaNනැවත (වඩා හොඳ වටිනාකමක් විය හැකි Falseසම්මත පෙළ ඇත්ත ගණනාවක් නිරූපණය වන නොවේ නම්). එය පරීක්ෂා කිරීම එක්තරා ආකාරයක වේදනාවක් (පයිතන්ගේ floatවර්ගයට ඇත්ත වශයෙන්ම ඒ සඳහා ක්‍රමවේදයක් අවශ්‍ය වේ) නමුත් දෝෂයක් ඇති නොකර ගණනය කිරීම් වලදී ඔබට එය භාවිතා කළ හැකි අතර ප්‍රති .ලය පමණක් පරීක්ෂා කළ යුතුය.
kindall

7
තවත් ව්යතිරේකයක් වන්නේ නූල් ය 'inf'. එක්කෝ infහෝ NaNසමඟ පෙරවදන කළ හැකි +හෝ -තවමත් පිළිගත හැකිය.
agf

4
ඔබට NaN සහ Inf සඳහා අසත්‍යය ආපසු ලබා දීමට අවශ්‍ය නම්, රේඛාව x = float (s) ලෙස වෙනස් කරන්න; ආපසු (x == x) සහ (x - 1! = x). ඉන්ෆ් සහ
නාන්

5
x-1 == xට වඩා කුඩා විශාල පාවෙන සඳහා සත්‍ය වේ inf. පයිතන් 3.2 සිට ඔබට math.isfiniteNaN හෝ අසීමිත නොවන සංඛ්‍යා පරික්ෂා කිරීමට භාවිතා කළ හැකිය , නැතහොත් ඊට පෙර math.isnanසහ දෙකම පරීක්ෂා කරන්න math.isinf.
ස්ටීව් ජෙසොප්

56

කොහොමද මේ:

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

එය සත්‍ය බවට පත්වන්නේ එකක් හෝ නොමැති නම් පමණි. ඉලක්කම් වල.

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

බොරු නැවත පැමිණේ

සංස්කරණය කරන්න: තවත් අදහසක් දුටුවා ... .replace(badstuff,'',maxnum_badstuff)වෙනත් අවස්ථා සඳහා එකතු කිරීමක් කළ හැකිය. ඔබ ලුණු පසුකරන්නේ නම් සහ අත්තනෝමතික රසකැවිලි නොවේ නම් (ref: xkcd # 974 ) මෙය හොඳ වනු ඇත: P.


7
කෙසේ වෙතත් මෙය negative ණ සංඛ්‍යා සඳහා ගණන් නොගනී.
මයිකල් බාටන්

5
හෝ වැනි on ාතකයන් සහිත සංඛ්‍යා 1.234e56(ඒවා +1.234E+56තවත් ප්‍රභේද කිහිපයක් ලෙස ලිවිය හැක ).
ඇල්ෆේ

re.match(r'^[+-]*(0[xbo])?[0-9A-Fa-f]*\.?[0-9A-Fa-f]*(E[+-]*[0-9A-Fa-f]+)$', 'str')අංකයක් තීරණය කිරීම සඳහා වඩා හොඳ කාර්යයක් කළ යුතුය (නමුත් සියල්ලම නොවේ, මම එසේ නොකියමි). මෙය භාවිතා කිරීමට මම නිර්දේශ නොකරමි, ප්‍රශ්න කරන්නාගේ මුල් කේතය භාවිතා කිරීම වඩා හොඳය.
බෝල්ඩ්රික්

ඔබ මෙම විසඳුමට අකමැති නම්, පහත් කිරීමට පෙර මෙය කියවන්න !
aloisdg codidact.com වෙත මාරු වීම

මිනිසා මේ වෙබ් අඩවියේ මා දැක ඇති හොඳම විසඳුම මෙයයි!
කරම් කුසායි

41

එය, කැත සහ මන්දගාමී පමණක් නොව, අවුල් සහගත බවක් පෙනේ.

එය පුරුදු වීමට යම් කාලයක් ගතවනු ඇත, නමුත් මෙය සිදු කිරීමේ පයිතොනික් ක්‍රමය මෙයයි. දැනටමත් පෙන්වා දී ඇති පරිදි, විකල්ප වඩාත් නරක ය. නමුත් මේ ආකාරයට දේවල් කිරීමේ තවත් වාසියක් ඇත: බහුමාපකය.

තාරාවන් ටයිප් කිරීම පිටුපස ඇති කේන්ද්‍රීය අදහස නම්, "එය තාරාවෙකු මෙන් ඇවිදින්නේ නම්, එය තාරාවෙකි." යමක් පාවෙන බවට පරිවර්තනය කළ හැකිදැයි ඔබ තීරණය කරන ආකාරය වෙනස් කිරීමට හැකි වන පරිදි ඔබට උප පංතියක් අවශ්‍ය යැයි ඔබ තීරණය කළහොත් කුමක් කළ යුතුද? නැතහොත් වෙනත් වස්තුවක් මුළුමනින්ම පරීක්ෂා කිරීමට ඔබ තීරණය කළහොත් කුමක් කළ යුතුද? ඉහත කේතය වෙනස් නොකර ඔබට මේවා කළ හැකිය.

වෙනත් භාෂා මෙම ගැටළු නිරාකරණය කරන්නේ අතුරු මුහුණත් භාවිතා කිරීමෙනි. වෙනත් නූලකට වඩා හොඳ කුමන විසඳුම පිළිබඳ විශ්ලේෂණය මම ඉතිරි කරමි. කාරණය නම්, සමීකරණයේ තාරාවන්ගේ යතුරු ලියන පැත්තේ පයිතන් තීරණය කර ඇති අතර, ඔබ පයිතන්හි බොහෝ වැඩසටහන් කිරීමට අදහස් කරන්නේ නම් ඔබට මෙවැනි වාක්‍ය ඛණ්ඩයක් භාවිතා කිරීමට සිදුවනු ඇත (නමුත් එයින් අදහස් නොවේ ඔබ එයට කැමති විය යුතුයි).

ඔබ සැලකිල්ලට ගත යුතු තවත් දෙයක්: පයිතන් වෙනත් භාෂා බොහොමයකට සාපේක්ෂව ව්‍යතිරේකයන් විසි කිරීම හා අල්ලා ගැනීම ඉතා වේගවත් ය (උදාහරණයක් ලෙස .Net ට වඩා 30 ගුණයක් වේගවත්). හෙක්, සුවිශේෂී නොවන, සාමාන්‍ය වැඩසටහන් තත්වයන් සන්නිවේදනය කිරීම සඳහා භාෂාව පවා ව්‍යතිරේකයන් විසි කරයි (ඔබ ලූපයක් සඳහා භාවිතා කරන සෑම අවස්ථාවකම). මේ අනුව, ඔබ සැලකිය යුතු ගැටළුවක් දකින තුරු මෙම කේතයේ ක්‍රියාකාරීත්වය ගැන මම ඕනෑවට වඩා කරදර නොවෙමි.


1
මූලික කාර්යයන් සඳහා පයිතන් ව්‍යතිරේක භාවිතා කරන තවත් පොදු ස්ථානයක් hasattr()වන්නේ getattr()ඇමතුමකින් පමණක් ඔතා ඇති a try/except. කෙසේ වෙතත්, ව්‍යතිරේකය හැසිරවීම සාමාන්‍ය ප්‍රවාහ පාලනයට වඩා මන්දගාමී වේ, එබැවින් බොහෝ විට එය සත්‍යයක් වනු ඇති දෙයක් සඳහා භාවිතා කිරීමෙන් කාර්ය සාධන ද .ුවමක් ලැබිය හැකිය.
kindall

ඔබට එක් ලයිනර් එකක් අවශ්‍ය නම්, ඔබ SOL
Basic

ලාභ ව්‍යතිරේකවල බලපෑම සම්බන්ධයෙන් “අවසරයට වඩා සමාව ඉල්ලීම වඩා හොඳය” යන අදහස පයිතොනික් වේ.
හෙල්ටන්බිකර්

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
මම එකඟවෙන්නේ නැහැ. එය සාමාන්‍ය භාවිතයේ දී බොහෝ දුරට අසීරු වන අතර, ඔබ ඒවා භාවිතා කරන විට is_complex_number () ඇමතුමක් ගොඩනඟා ගැනීම වඩා හොඳ වනු ඇත.
ජිමිනියන්

3
ඔබට float()දේවල් සම්පූර්ණයෙන්ම ඉවත් කර complex()ඇමතුම සාර්ථක වීමට පරීක්ෂා කරන්න . විග්‍රහ කරන සෑම දෙයක්ම විග්‍රහ float()කළ හැකිය complex().
ඇල්ෆ්

මෙම ශ්‍රිතය පණ්ඩස්ගේ NaNs සහ Inf අගයන් සංඛ්‍යාත්මක අගයන් ලෙස ලබා දෙනු ඇත.
fixxxer

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

Negative ණ සංඛ්‍යා සඳහා පමණක් එකතු කරන්න lstrip():

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

දැන් අපට විශ්වීය ක්‍රමයක් ලැබේ:

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

2
වැනි 1.234e56හා සමාන දේවල් හසුරුවන්නේ නැත . එසේම, 99999999999999999999e99999999999999999999එය අංකයක් නොවන බව ඔබ සොයා ගන්නේ කෙසේදැයි මම උනන්දු වෙමි . එය විග්‍රහ කිරීමට උත්සාහ කිරීම ඉක්මනින් සොයා ගනී.
ඇල්ෆේ

මෙය මීටර් 50 නූල් ලැයිස්තුවක පිළිගත් විසඳුමට වඩා ~ 30% වේගයෙන් ද 5k නූල් ලැයිස්තුවක 150% වේගයෙන් ද ධාවනය වේ. 👏
සෙව් අවර්බැක්

15

සී අනුකරණය කරන්න #

C # හි පරිමාණ අගයන් විග්‍රහ කිරීම සඳහා වෙනස් කාර්යයන් දෙකක් ඇත:

  • පාවෙන.පාර්ස් ()
  • Float.TryParse ()

float.parse ():

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

සටහන: මම ව්‍යතිරේකය TypeError ලෙස වෙනස් කළේ ඇයි කියා ඔබ සිතන්නේ නම්, මෙන්න ප්‍රලේඛනය .

float.try_parse ():

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

සටහන: බූලියන් 'අසත්‍යය' නැවත ලබා දීමට ඔබට අවශ්‍ය නැත, මන්ද එය තවමත් අගය වර්ගයකි. කිසිවක් අසමත් වන නිසා එය වඩා හොඳ නැත. ඇත්ත වශයෙන්ම, ඔබට වෙනස් දෙයක් අවශ්‍ය නම් ඔබට අසමත් පරාමිතිය ඔබට අවශ්‍ය ඕනෑම දෙයකට වෙනස් කළ හැකිය.

'විග්‍රහය ()' සහ 'try_parse ()' ඇතුළත් කිරීම සඳහා පාවෙන කාලය දීර් To කිරීම සඳහා මෙම ක්‍රම එකතු කිරීම සඳහා ඔබට 'පාවෙන' පන්තිය වඳුරන් කළ යුතුය.

ඔබට පෙර පැවති කාර්යයන්ට ගරු කිරීමට අවශ්‍ය නම් කේතය මෙවැනි දෙයක් විය යුතුය:

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

මහා පයිතොනාස් ශුද්ධාසනය ෂාපිසස්ට පැවසුවේ, “ඔබට කළ හැකි ඕනෑම දෙයක් මට වඩා හොඳින් කළ හැකිය; මට වඩා හොඳ දෙයක් මට කළ හැකිය.”


මම බොහෝ විට JS හි කේතකරනය කර ඇති අතර ඇත්ත වශයෙන්ම මෙය පරීක්‍ෂා නොකළ නිසා සුළු දෝෂ ඇති විය හැක. ඔබ යමක් දුටුවහොත්, මගේ වැරදි නිවැරදි කිරීමට නිදහස් වන්න.
ඉවාන් ප්ලේස්

සංකීර්ණ සංඛ්‍යා සඳහා සහය එක් කිරීම සඳහා att මැතිව් විල්කොක්සන් ගේ පිළිතුර බලන්න. stackoverflow.com/a/3335060/290340 .
ඉවාන් ප්ලේස්

1
!ඒ වෙනුවට භාවිතා කිරීම notසුළු දෝෂයක් විය හැකි නමුත්, ඔබට අනිවාර්යයෙන්ම ගොඩනඟන ලද floatCPython සඳහා ගුණාංග පැවරිය නොහැක .
බ්ලැක් ජැක්

15

සංඛ්‍යා නොවන නූල් සඳහා, try: except:සාමාන්‍ය ප්‍රකාශනවලට වඩා මන්දගාමී වේ. වලංගු සංඛ්‍යා වල නූල් සඳහා, රීජෙක්ස් මන්දගාමී වේ. එබැවින් සුදුසු ක්‍රමය ඔබේ ආදානය මත රඳා පවතී.

ඔබ කාර්ය සාධන බඳින්න සිටින බව ඔබ දුටුවේ නම්, ඔබ නමින් නව තෙවන පාර්ශවීය මොඩියුලය භාවිතා කළ හැකිය fastnumbers නමින් කාර්යය සපයන isfloat . සම්පූර්ණ අනාවරණය, මම කතුවරයා වෙමි. මම එහි ප්‍රති results ල පහත වේලාවට ඇතුළත් කර ඇත්තෙමි.


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: සංඛ්‍යාත්මක ආදානය සඳහා වේගවත් නමුත් අවලංගු ආදානය සඳහා ඉතා මන්දගාමී විය
  • ආදානය අවලංගු වූ විට regex ඉතා කාර්යක්ෂම වේ
  • fastnumbers අවස්ථා දෙකේදීම ජය ගනී

මම නිවැරදි කර සිටිමි: -} එය මෙය කරන බවක් පෙනෙන්නට නැත. සමහර විට වැනි නම් භාවිතා prep_code_basisසහ prep_code_re_methodමගේ වැරැද්ද සිදු වෙන්නේ නැහැ.
ඇල්ෆ්

අවම වශයෙන් isfloatශ්‍රිතය සඳහා ඔබේ මොඩියුලය ක්‍රියා කරන ආකාරය පැහැදිලි කිරීමට ඔබට අවශ්‍යද?
සොලමන් උකෝ

OlSolomonUcko මෙහි වචන පරික්ෂා කිරීමේ කොටස සඳහා ප්‍රභව කේතයට සබැඳියක් ඇත: github.com/SethMMorton/fastnumbers/blob/v1.0.0/src/… . මූලික වශයෙන්, එය එක් එක් අක්‍ෂරය හරහා අනුපිළිවෙලින් ගමන් කරන අතර එය වලංගු පාවීමක් සඳහා රටාවක් අනුගමනය කරන බව තහවුරු කරයි. ආදානය දැනටමත් අංකයක් නම්, එය වේගවත් PyFloat_Check භාවිතා කරයි .
සෙත්මෝර්ටන්

1
මම මේ විසඳුම තහවුරු මෙම නූල් හොඳම විකල්ප එරෙහිව පරීක්ෂා බොහෝ දුරට වේගවත්ම. දෙවන වේගවත්ම ක්‍රමය str(s).strip('-').replace('.','',1).isdigit()වන්නේ දළ වශයෙන් 10x මන්දගාමී වීමයි!
ඇලෙක්සැන්ඩර් මැක්ෆාර්ලන්

14

මෙය විශේෂයෙන් පැරණි බව මම දනිමි, නමුත් මෙය සොයා ගන්නා ඕනෑම කෙනෙකුට ඉතා වටිනා විය හැකි ඉහළම ඡන්දය දුන් පිළිතුරේ නැති තොරතුරු ආවරණය වන බව මම විශ්වාස කරමි.

ඔබට පිළිගැනීමට කිසියම් ආදානයක් අවශ්‍ය නම් පහත සඳහන් එක් එක් ක්‍රම ගණනය කිරීම සමඟ ඒවා සම්බන්ධ කරන්න. (අපි 0-255, ආදිය වෙනුවට පූර්ණ සංඛ්‍යා වල වාචික අර්ථ දැක්වීම් භාවිතා කරමු යැයි සිතමු.)

x.isdigit() x යනු පූර්ණ සංඛ්‍යාවක් දැයි පරීක්ෂා කිරීම සඳහා හොඳින් ක්‍රියා කරයි.

x.replace('-','').isdigit() x negative ණදැයි පරීක්ෂා කිරීම සඳහා හොඳින් ක්‍රියා කරයි. (පරීක්ෂා කරන්න - පළමු ස්ථානයේ)

x.replace('.','').isdigit() x යනු දශමයක් දැයි පරීක්ෂා කිරීම සඳහා හොඳින් ක්‍රියා කරයි.

x.replace(':','').isdigit() x අනුපාතය දැයි පරීක්ෂා කිරීම සඳහා හොඳින් ක්‍රියා කරයි.

x.replace('/','',1).isdigit() x යනු භාගයක් දැයි පරීක්ෂා කිරීම සඳහා හොඳින් ක්‍රියා කරයි.


1
අතුරු කොටස් සඳහා වුවද, ඔබ බොහෝ විට කළ යුතු x.replace('/','',1).isdigit()හෝ වෙනත් ආකාරයකින් 4/7/2017 වැනි දිනයන් සංඛ්‍යා ලෙස වැරදි ලෙස අර්ථකථනය කරනු ඇත.
යුක්සුන් චෙන්

කොන්දේසි දාමය කළ හැකි හොඳම ක්‍රම සඳහා: stackoverflow.com/q/3411771/5922329
ඩැනියෙල් බ්‍රවුන්

13

මෙම පිළිතුර මඟින් පියවරෙන් පියවර මාර්ගෝපදේශය සපයයි.

  • ධනාත්මක නිඛිලය
  • ධනාත්මක / negative ණ - පූර්ණ සංඛ්‍යා / පාවෙන
  • අංකය පරික්ෂා කිරීමේදී "NaN" (අංකයක් නොවේ) නූල් ඉවතලන්නේ කෙසේද?

නූල් ධනාත්මක පූර්ණ සංඛ්‍යාවක් දැයි පරීක්ෂා කරන්න

str.isdigit()ලබා දී ඇති නූල් ධනාත්මක පූර්ණ සංඛ්‍යාවක් දැයි පරීක්ෂා කිරීමට ඔබට භාවිතා කළ හැකිය .

නියැදි ප්‍රති Results ල:

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

ධනය ධනාත්මක / negative ණ ලෙස පරික්ෂා කරන්න - නිඛිල / පාවෙන

str.isdigit()නූල negative ණ සංඛ්‍යාවක් හෝ පාවෙන අංකයක් Falseනම් ආපසු එයි . උදාහරණයක් වශයෙන්:

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

ඔබට the නිඛිල සංඛ්‍යාවක් පරික්ෂා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"NAN" (අංකයක් නොවේ) සඳහා නැවත පැමිණෙනු ඇත, මන්ද පයිතන් සඳහා එය වලංගු පාවෙන බැවින් එය අංකයක් නොවේ. උදාහරණයක් වශයෙන්:

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

පාවීමට () නිශ්චිතවම අදහස් කර ඇත්තේ ඒ සඳහා පමණක් වන බැවින්, පාවීමට වාත්තු කිරීම සහ ValueError අල්ලා ගැනීම වේගවත්ම ක්‍රමය විය හැකිය. මෙම ක්‍රියාව සඳහා සුසර කර නොමැති නිසා නූල් විග්‍රහ කිරීම (රීජෙක්ස්, ආදිය) අවශ්‍ය ඕනෑම දෙයක් මන්දගාමී වනු ඇත. මගේ $ 0.02.


11
ඔබේ "2e-2" ඩොලර් ද පාවෙන ය (පාවෙන භාවිතා කිරීම සඳහා අතිරේක තර්කයක් :)
tzot

8
ztzot කිසි විටෙකත් මුදල් වටිනාකමක් නිරූපණය කිරීම සඳහා පාවෙන භාවිතා නොකරන්න.
ලූක්

6
Ue ලූක්: මුදල් වටිනාකම් නිරූපණය කිරීම සඳහා පාවෙන භාවිතා කිරීමට මා කිසි විටෙකත් යෝජනා නොකළද, මම ඔබ සමඟ සම්පූර්ණයෙන්ම එකඟ වෙමි; මම කිව්වේ මුදල් වටිනාකම් පාවෙන ලෙස නිරූපණය කළ හැකි බවයි :)
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



1
s.isdecimal()නූල snegative ණ නොවන පූර්ණ සංඛ්‍යාවක් දැයි පරීක්ෂා කරයි. ප්‍රතික්ෂේප කරන s.isnumeric()අක්ෂර ඇතුළත් වේ int().
jfs

9

වේගවත්ම ක්‍රමය කුමක්දැයි බැලීමට මට අවශ්‍ය විය. සමස්තයක් ලෙස හොඳම හා වඩාත්ම ස්ථාවර ප්‍රති results ල ලබා දුන්නේ check_replaceශ්‍රිතයෙනි. වේගවත්ම ප්‍රති results 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 සමඟ ප්‍රති results ල මෙන්න:

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 සමඟ ප්‍රති results ල මෙන්න:

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 හි PyPy 2.7.13 සමඟ ඇති ප්‍රති results ල මෙන්න:

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
අවලංගු අවස්ථා සඳහාද ඔබ කාර්ය සාධනය පරීක්ෂා කළ යුතුය. මෙම සංඛ්‍යා සමඟ කිසිදු ව්‍යතිරේකයක් මතු නොවන අතර එය හරියටම "මන්දගාමී" කොටසයි.
Ugo Méda

1
@ UgoMéda මම 2013 සිට ඔබේ උපදෙස් ලබාගෙන එය කළෙමි :)
රොන් රයිටර්

"සාර්ථක වාත්තු කිරීමක් පරීක්ෂා කිරීම නිවැරදි එකම ක්‍රමය බව කරුණාවෙන් සලකන්න" <- මෙය ඇත්ත වශයෙන්ම සත්‍ය නොවේ. ඉහත මගේ පිළිතුරේ ඇති රීජෙක්ස්ප් භාවිතා කර මම ඔබේ පරීක්ෂණය ධාවනය කර ඇත්තෙමි. ඉහත පිළිතුරට මම ප්‍රති results ල එකතු කරමි.
ඩේවිඩ් ලුං මැඩිසන් ස්ටෙලර්

අහම්බෙන්, විනෝදජනක කරුණක් ලෙස, ඔබේ නරක සංඛ්‍යා නිර්මාපකයාට ඇත්ත වශයෙන්ම සමහර නීතිමය සංඛ්‍යා නිර්මාණය කළ හැකිය, එය තරමක් දුර්ලභ වනු ඇත. :)
ඩේවිඩ් ලුං මැඩිසන් ස්ටෙලර්

8

එබැවින් ඒ සියල්ල එකට තැබීම සඳහා, නාන්, අනන්තය සහ සංකීර්ණ සංඛ්‍යා පරික්ෂා කිරීම (ඒවා j, i නොව 1 + 2j සමඟ නිශ්චිතව දක්වා ඇති බව පෙනේ) එහි ප්‍රති results ලය වනුයේ:

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

මෙතෙක් හොඳම පිළිතුර. ස්තූතියි
anish

6

ආදානය පහත පරිදි විය හැකිය:

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


1-සාමාන්‍ය ආදානය:

මෙම ශ්‍රිතයේ ආදානය සියල්ල විය හැකිය!

දී ඇති විචල්‍යය සංඛ්‍යාත්මකද යන්න සොයා ගනී. සංඛ්‍යාත්මක නූල් විකල්ප ලකුණ, ඉලක්කම් ගණන, විකල්ප දශම කොටස සහ විකල්ප on ාතීය කොටසකින් සමන්විත වේ. මේ අනුව + 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 ශ්‍රිතය

දී ඇති විචල්‍යය පාවෙන දැයි සොයා ගනී. පාවෙන නූල් විකල්ප ලකුණකින්, ඉලක්කම් ගණනකින් සමන්විත වේ, ...

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-සංඛ්‍යාත්මක ආදානය:

int අගය හඳුනා ගන්න:

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

රයන් එන් යෝජනා කරයි

ඔබට NaN සහ Inf සඳහා අසත්‍යය ආපසු ලබා දීමට අවශ්‍ය නම්, රේඛාව x = float (s) ලෙස වෙනස් කරන්න; ආපසු (x == x) සහ (x - 1! = x). මෙය Inf සහ NaN හැර අනෙකුත් සියලුම පාවෙන සඳහා සත්‍යය ලබා දිය යුතුය

නමුත් මෙය එතරම් සාර්ථක නොවේ, මන්ද ප්‍රමාණවත් තරම් විශාල පාවෙන සඳහා, x-1 == xනැවත සත්‍ය වේ. උදාහරණයක් වශයෙන්,2.0**54 - 1 == 2.0**54


3

මම ඔබේ විසඳුමක් හොඳයි හිතන්න, නමුත් එහි වේ නිවැරදි regexp ක්රියාත්මක කිරීම.

අසාධාරණ යැයි මා සිතන මෙම පිළිතුරු කෙරෙහි රීජෙක්ස් වෛරයක් ඇති බව පෙනේ, රීජෙක්ස් සාධාරණ ලෙස පිරිසිදු හා නිවැරදි හා වේගවත් විය හැකිය. එය සැබවින්ම රඳා පවතින්නේ ඔබ කිරීමට උත්සාහ කරන දේ මත ය. මුල්ම ප්‍රශ්නය වූයේ “නූලක් අංකයක් (පාවෙන) ලෙස නිරූපණය කළ හැකිදැයි පරීක්ෂා කරන්නේ කෙසේද” (ඔබේ මාතෘකාවට අනුව). එය වලංගු දැයි ඔබ පරීක්ෂා කළ පසු සංඛ්‍යා / පාවෙන අගය භාවිතා කිරීමට ඔබට අවශ්‍ය වනු ඇත, එම අවස්ථාවේදී ඔබගේ උත්සාහය / හැරෙන්නට බොහෝ අර්ථවත් වේ. නමුත් යම් හේතුවක් නිසා, ඔබ යන්තම් බව තහවුරු කිරීමට අවශ්ය නම්, string යනු අංකයඑවිට රීජෙක්ස් ද හොඳින් ක්‍රියා කරයි, නමුත් නිවැරදි වීම දුෂ්කර ය. මම හිතන්නේ මේ දක්වා ඇති බොහෝ රීජෙක්ස් පිළිතුරු, පයිතන් සම්බන්ධයෙන් සැලකිලිමත් වන තාක් දුරට පාවෙන පූර්ණ සංඛ්‍යාවක් (".7" වැනි) නොමැතිව නූල් නිසි ලෙස විග්‍රහ නොකරන්න. භාගික කොටස අවශ්‍ය නොවන තනි රීජෙක්ස් එකක පරීක්ෂා කිරීම තරමක් උපක්‍රමශීලී ය. මෙය පෙන්වීමට මම රීජෙක්ස් දෙකක් ඇතුළත් කර ඇත්තෙමි.

එය "අංකයක්" යනු කුමක්ද යන්න පිළිබඳ සිත්ගන්නාසුලු ප්‍රශ්නය මතු කරයි. පයිතන් වල පාවෙන ලෙස වලංගු වන "inf" ඔබ ඇතුළත් කරනවාද? නැතහොත් ඔබ "සංඛ්‍යා" වන සංඛ්‍යා ඇතුළත් නමුත් සමහර විට පයිතන් වලින් නිරූපණය කළ නොහැක (පාවෙන උපරිමයට වඩා විශාල සංඛ්‍යා වැනි).

ඔබ සංඛ්‍යා විග්‍රහ කරන ආකාරය පිළිබඳ ද අවිනිශ්චිතතාවයන් ඇත. උදාහරණයක් ලෙස, "--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

Re රොන්-රයිටර්ගේ පිළිතුරෙහි මිණුම් සලකුණු කේතය ධාවනය කිරීමෙන් පෙන්නුම් කරන්නේ මෙම රීජෙක්ස් ඇත්ත වශයෙන්ම සාමාන්‍ය රීජෙක්ස් වලට වඩා වේගවත් වන අතර ව්‍යතිරේකයට වඩා නරක අගයන් හැසිරවීමේ දී වඩා වේගවත් වන අතර එය යම් අර්ථයක් ඇති කරයි. ප්රතිපල:

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

මෙම කේතය රීජෙක්ස් භාවිතා කරමින් on ාතයන්, පාවෙන සහ පූර්ණ සංඛ්‍යා හසුරුවයි.

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

සත්‍ය සහ අසත්‍යයට වඩා ප්‍රයෝජනවත් අගයන් ආපසු ලබා දීමෙන් ඔබට ව්‍යතිරේක තාක්‍ෂණය ප්‍රයෝජනවත් ආකාරයකින් සාමාන්‍යකරණය කළ හැකිය. උදාහරණයක් ලෙස මෙම ශ්‍රිතය උපුටා දැක්වීම් වටකුරු නූල් තබන නමුත් සංඛ්‍යා පමණක් ඉතිරි කරයි. ආර් සඳහා විචල්ය නිර්වචන කිහිපයක් කිරීමට ඉක්මන් හා අපිරිසිදු පෙරණයක් සඳහා මට අවශ්ය වූයේ එයයි.

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 - නූල පූර්ණ සංඛ්‍යාවක් නිරූපණය කරන්නේ නම් මට පූර්ණ සංඛ්‍යා ප්‍රති result ලයක් අවශ්‍ය විය

2 - දත්ත ව්‍යුහයකට ඇලී සිටීමට මට අංකයක් හෝ නූල් ප්‍රති result ලයක් අවශ්‍ය විය

එබැවින් මෙම ව්‍යුත්පන්නය නිෂ්පාදනය කිරීම සඳහා මම මුල් කේතය අනුවර්තනය කළෙමි:

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')
අපොහොසත් වේ

othegeotheory, ඔබ අදහස් කරන්නේ "ප්‍රතිචාර දැක්වීමට අපොහොසත් වීම" යන්නයි.
සොලමන් උකෝ

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.