how to check the data type in python




كيف أتحقق من أن السلسلة عبارة عن رقم(عائم)؟ (20)

ما هي أفضل طريقة ممكنة للتحقق مما إذا كان يمكن تمثيل السلسلة كرقم في بايثون؟

الوظيفة التي لدي حاليا هي:

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

الذي ، ليس فقط بشع وبطيء ، يبدو عالي الكعب. ومع ذلك لم أجد طريقة أفضل لأن استدعاء float في الوظيفة الرئيسية هو أسوأ من ذلك.


التي ، ليس فقط قبيحة وبطيئة

سأناقش كلاهما

سيكون التعابير المعتادة أو تحليل السلسلة الأخرى أقبح وأبطأ.

لست متأكدا من أن أي شيء يمكن أن يكون أسرع بكثير مما سبق. انها تدعو وظيفة والعودة. لا تقدم أداة Try / Catch الكثير من الحمل لأن الاستثناء الأكثر شيوعًا يتم اكتشافه بدون إجراء بحث شامل عن إطارات المكدس.

المشكلة هي أن أي دالة تحويل رقمية لها نوعان من النتائج

  • رقم ، إذا كان الرقم صالحًا
  • رمز الحالة (على سبيل المثال ، عبر errno) أو الاستثناء لإظهار أنه لا يمكن تحليل رقم صالح.

C (على سبيل المثال) الاختراق حول هذا عدد من الطرق. بيثون تضعها بوضوح وصراحة.

أعتقد أن الشفرة الخاصة بك للقيام بذلك مثالية.


الذي ، ليس فقط بشع وبطيء ، يبدو عالي الكعب.

قد يستغرق الأمر بعض التعود ، ولكن هذه هي الطريقة المثالية للقيام بذلك. وكما أشير بالفعل ، فإن البدائل أسوأ. ولكن هناك ميزة واحدة أخرى للقيام بهذه الأمور بهذه الطريقة: تعدد الأشكال.

الفكرة الأساسية وراء كتابة البط هي أنه "إذا كان يمشي ويتحدث وكأنه بطة ، فذلك هو البط". ماذا لو قررت أنك بحاجة إلى سلسلة فئة فرعية بحيث يمكنك تغيير كيفية تحديد ما إذا كان يمكن تحويل شيء ما إلى عوامة؟ أو ماذا إذا قررت اختبار بعض الأشياء الأخرى بالكامل؟ يمكنك القيام بهذه الأشياء دون الحاجة إلى تغيير الرمز أعلاه.

اللغات الأخرى حل هذه المشاكل باستخدام واجهات. سأحفظ تحليل الحل الذي هو أفضل لمؤشر آخر. على الرغم من ذلك ، فإن النقطة هي أن الثعبان هو بالتأكيد على الجانب المكتوب من المعادلة ، وعليك أن تعتاد على بناء الجملة على هذا النحو إذا كنت تخطط للقيام بالكثير من البرمجة في بايثون (لكن هذا لا يعني عليك أن تحب ذلك بالطبع).

هناك أمر آخر قد ترغب في أخذه بعين الاعتبار: بيثون سريعة في إلقاء الاستثناءات والتقاطها مقارنة بالكثير من اللغات الأخرى (أسرع 30 مرة من .Net على سبيل المثال). هيك ، اللغة نفسها حتى يلقي استثناءات لتوصيل شروط البرنامج غير استثنائية ، العادي (في كل مرة تستخدم فيها حلقة for). وبالتالي ، لا داعي للقلق كثيرا بشأن جوانب الأداء لهذا القانون حتى تلاحظ مشكلة كبيرة.


أعلم أن هذا الأمر قديم بشكل خاص ولكني أود أن أضيف إجابة أعتقد أنها تغطي المعلومات المفقودة من أعلى إجابة صوتية يمكن أن تكون ذات قيمة كبيرة لأي شخص يجده:

لكل طريقة من الطرق التالية قم بتوصيلهم بالعد إذا احتجت إلى قبول أي إدخال. (بافتراض أننا نستخدم تعريفات صوتية للأعداد الصحيحة بدلاً من 0-255 ، إلخ.)

x.isdigit() يعمل بشكل جيد للتحقق ما إذا كان x عدداً صحيحاً.

x.replace('-','').isdigit() يعمل بشكل جيد للتحقق مما إذا كان x سلبي (تحقق - في المركز الأول)

x.replace('.','').isdigit() يعمل بشكل جيد للتحقق إذا كان x رقم عشري.

x.replace(':','').isdigit() يعمل بشكل جيد للتحقق ما إذا كانت x نسبة.

x.replace('/','',1).isdigit() يعمل بشكل جيد للتحقق إذا كان x جزءًا.


بالنسبة إلى سلاسل غير أرقام ، try: except: أبطأ من التعبيرات العادية. بالنسبة لسلاسل الأرقام الصالحة ، يكون التعبير العادي أبطأ. لذلك ، تعتمد الطريقة المناسبة على المدخلات الخاصة بك.

إذا وجدت أنك في أحد fastnumbers الأداء ، فيمكنك استخدام وحدة نمطية جديدة تابعة لجهة خارجية تسمى fastnumbers توفر وظيفة تسمى isfloat . الكشف الكامل ، أنا المؤلف. لقد أدرجت نتائجها في التوقيت أدناه.

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 في كلتا الحالتين

توفر هذه الإجابة دليل خطوة بخطوة يحتوي على وظيفة مع أمثلة للعثور على السلسلة:

  • عدد صحيح موجب
  • موجب / سلبي - عدد صحيح / عائم
  • كيفية تجاهل الجمل "NaN" (وليس رقمًا) أثناء التحقق من الرقم؟

تحقق مما إذا كانت السلسلة عبارة عن عدد صحيح موجب

يمكنك استخدام isdigit() للتحقق ما إذا كانت سلسلة المعطى عددًا صحيحًا موجبًا .

نتائج العينة:

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

تحقق من وجود سلسلة موجبة / سلبية - عدد صحيح / عدد عشري

str.isdigit() بإرجاع False إذا كانت السلسلة رقم سالب أو رقم عائم. فمثلا:

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

إذا كنت تريد أيضًا التحقق من الأعداد الصحيحة والسلبية ، فيمكنك كتابة وظيفة مخصصة للتحقق منها على النحو التالي:

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" (ليست رقمًا) نظرًا لأن python عبارة عن عوامة صحيحة تمثل أنها ليست رقمًا. فمثلا:

>>> is_number('NaN')
True

لمعرفة ما إذا كان الرقم "NaN" ، يمكنك استخدام math.isnan() كـ:

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

>>> math.isnan(nan_num)
True

أو إذا كنت لا ترغب في استيراد مكتبة إضافية للتحقق من ذلك ، يمكنك ببساطة التحقق من ذلك من خلال مقارنةها مع نفسها باستخدام == . ترجع Python False عندما تتم مقارنة nan float بنفسها. فمثلا:

# `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: Each operation for each check depending on the type of number comes with additional overhead. Choose the version of is_number function which fits your requirement.


دعنا نقول لديك أرقام في السلسلة. str = "100949" وترغب في التحقق مما إذا كان يحتوي على أرقام فقط

if str.isdigit():
returns TRUE or FALSE 

isdigit مستندات

وإلا فإن الطريقة الخاصة بك تعمل بشكل رائع للعثور على عدد من الأرقام في سلسلة.


فعلت بعض اختبار السرعة. دعنا نقول أنه إذا كان من المرجح أن يكون الرقم هو رقم المحاولة / الاستثناء هو أسرع ما يمكن.إذا كان من غير المحتمل أن يكون الرقم رقمًا وكنت مهتمًا بفحص Integer ، فإنه يستحق القيام ببعض الاختبارات (isdigit plus العنوان '-'). إذا كنت مهتمًا بالتحقق من رقم عائم ، فعليك استخدام ميزة try / except code whitout escape.


في حالة البحث عن أعداد صحيحة (موجبة وغير موقعة) بدلاً من floats ، يمكنك استخدام الدالة isdigit() لكائنات السلسلة.

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

طرق سلسلة - isdigit()

هناك أيضا شيء على سلاسل Unicode ، وأنا لست على دراية Unicode - هو عشري / عشري


كنت بحاجة لتحديد ما إذا كانت سلسلة يلقي في أنواع أساسية (تعويم ، كثافة العمليات ، 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) 

لذا لوضع كل ذلك معا ، والتحقق من نان ، اللانهاية والأرقام المعقدة (يبدو أنها محددة مع ي ، وليس أنا ، أي 1 + 2J) فإنه يؤدي إلى:

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

من المحتمل أن يكون وضع تعويم واصطياد القيمة ValueError أسرع طريقة ، حيث أن float () مخصص لهذا الغرض على وجه التحديد. أي شيء آخر يتطلب تحليل سلسلة (regex ، الخ) من المرجح أن يكون أبطأ بسبب حقيقة أنه لم يتم ضبطه لهذه العملية. بلدي 0.02 دولار.


هناك استثناء واحد قد ترغب في أخذه بعين الاعتبار: السلسلة "NaN"

إذا كنت تريد أن يقوم is_number بإرجاع FALSE لـ "NaN" ، فلن يعمل هذا الرمز لأن Python تقوم بتحويله إلى تمثيل له لرقم ليس رقمًا (الحديث عن مشكلات الهوية):

>>> float('NaN')
nan

بخلاف ذلك ، ينبغي أن أشكرك بالفعل على جزء الشفرة الذي أستخدمه الآن على نطاق واسع. :)

G.


يقترح ريان

إذا كنت تريد إرجاع False لـ NaN و Inf ، غيّر السطر إلى x = float (s)؛ return (x == x) و (x - 1! = x). هذا يجب إرجاع True لكافة العوامات باستثناء Inf و NaN

ولكن هذا لا ينجح تمامًا ، نظرًا لأن x-1 == x يعود بشكل صحيح إلى عوامات كبيرة بما فيه الكفاية. على سبيل المثال ، 2.0**54 - 1 == 2.0**54



Here's my simple way of doing it. Let's say that I'm looping through some strings and I want to add them to an array if they turn out to be numbers.

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

Replace the myvar.apppend with whatever operation you want to do with the string if it turns out to be a number. The idea is to try to use a float() operation and use the returned error to determine whether or not the string is a number.


I also used the function you mentioned, but soon I notice that strings as "Nan", "Inf" and it's variation are considered as number. So I propose you improved version of your function, that will return false on those type of input and will not fail "1e3" variants:

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

If you want to know if the entire string can be represented as a number you'll want to use a regexp (or maybe convert the float back to a string and compare it to the source string, but I'm guessing that's not very fast).


To check if the input value is a float , you can compare the type of the input to a float

def isFloat(s):
    realFloat = 0.1

    if type(s) == type(realFloat):
        return True
    else:
        return False

عائدات:

False     # s = 5
True      # s = 1.2345

فإن آخر الأصلي يعود في الواقع Trueل s = 5أنه هو رقم (صحيح) ويمكنك يلقي intإلى floatدون ValueError. إذا كنت تحاول التحقق من أنها فعلية floatبدلاً من مجرد رقم ، فستحتاج إلى حساب هذه الحالة.


You can generalize the exception technique in a useful way by returning more useful values than True and False. For example this function puts quotes round strings but leaves numbers alone. Which is just what I needed for a quick and dirty filter to make some variable definitions for R.

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:]), ')'

You may use regex.

number = raw_input("Enter a number: ")
if re.match(r'^\d+$', number):
    print "It's integer"
    print int(number)
elif re.match(r'^\d+\.\d+$', number):
    print "It's float"
    print float(number)
else:
    print("Please enter a number")






type-conversion