Как проверить, является ли строка числом (с плавающей точкой)?

голоса
1k

Каков наилучший способ проверить, если строка может быть представлена ​​в виде числа в Python?

Функция Сейчас у меня прямо сейчас:

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

Который не только некрасиво и медленно, кажется неуклюжим. Однако я не нашел лучший способ , потому что вызов floatв основной функции еще хуже.

Задан 09/12/2008 в 21:03
источник пользователем
На других языках...                            


34 ответов

голоса
1k

В случае , если вы ищете для разбора (положительных, без знака) целых чисел вместо поплавков, вы можете использовать isdigit()функцию для строковых объектов.

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

Методы String - isdigit()

Там также то , что на строках Unicode, что я не слишком хорошо знаком с Unicode - десятичный / десятичные

Ответил 09/12/2008 в 21:15
источник пользователем

голоса
556

Который не только некрасиво и медленно

Я спорю обоих.

Регулярное выражение или другая строка синтаксического анализа будет уродливой и медленнее.

Я не уверен, что что-нибудь может быть гораздо быстрее, чем выше. Она вызывает функцию и возвращает. Try / Поймать не вносит много накладных расходов, поскольку наиболее распространенное исключение ловятся без обширного поиска кадров стека.

Вопрос заключается в том, что любая числовая функция преобразования имеет два вида результатов

  • Число, если число является действительным
  • Код состояния (например, с помощью егто) или исключение, чтобы показать, что ни один действительный номер не может быть разобран.

С (в качестве примера) хаки вокруг этого несколько способов. Python кладет ее четко и ясно.

Я думаю, что ваш код делает это идеально.

Ответил 09/12/2008 в 21:30
источник пользователем

голоса
62

Существует одно исключение, что вы можете принять во внимание: строка «NaN»

Если вы хотите is_number вернуть FALSE для «NaN» этот код не будет работать, как Python преобразует его в представлении число, которое не является числом (разговор о вопросах идентичности):

>>> float('NaN')
nan

В противном случае, я на самом деле должен поблагодарить вас за кусок кода Теперь я использую экстенсивно. :)

Г.

Ответил 01/09/2010 в 15:06
источник пользователем

голоса
56

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

Поплавок обозначение»0,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

EDIT: Результаты тестов

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

введите описание изображения здесь

Ответил 13/05/2014 в 20:28
источник пользователем

голоса
51

как насчет этого:

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

которая возвращает истину, если не существует один или нет ". в строке цифр.

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

вернет ложь

Редактирование: только что видел еще один комментарий ... добавление .replace(badstuff,'',maxnum_badstuff)в других случаях может быть сделано. если вы передаете соль и не произвольны приправы (реф: XKCD # 974 ) это будет делать хорошо: P

Ответил 25/05/2012 в 23:22
источник пользователем

голоса
37

Обновленный после Альфея указал, что вам не нужно, чтобы проверить поплавок отдельно, как комплекс обрабатывает как:

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
Ответил 26/07/2010 в 14:10
источник пользователем

голоса
37

Который не только некрасиво и медленно, кажется неуклюжим.

Это может занять некоторое время, чтобы привыкнуть, но это вещий способ сделать это. Как уже отмечалось, альтернативы хуже. Но есть еще одно преимущество делать вещи таким образом: полиморфизм.

Основная идея утиной типизации является то, что «если он ходит и говорит как утка, то это утка.» Что делать, если вы решили, что вам нужно подкласс строки, так что вы можете изменить, как вы определить, есть ли что-то может быть преобразованы в поплавок? Или что, если вы решили испытать какой-нибудь другой объект целиком? Вы можете сделать эти вещи без необходимости изменять код выше.

Другие языки решают эти проблемы с помощью интерфейсов. Я спасу анализ которого решение лучше другого потока. Дело в том, однако, является то, что питон явно на утиной типизации стороне уравнения, и вы, вероятно, придется привыкать к синтаксису, как это, если вы планируете делать много программирования на Python (но это не значит, вы должны любить его, конечно).

Еще одна вещь, которую вы можете принять во внимание: Python довольно быстро в бросать и ловить исключения по сравнению с множеством других языков (30x быстрее, чем .Net, например). Хек, сам язык даже бросает исключения для общения, не исключительные, нормальные условия программы (каждый раз, когда вы используете для цикла). Таким образом, я бы не слишком беспокоиться об аспектах производительности этого кода, пока вы не заметите существенную проблему.

Ответил 11/12/2008 в 05:56
источник пользователем

голоса
17

Для 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
Ответил 08/09/2015 в 08:42
источник пользователем

голоса
14

Для строк , не являющихся чисел, try: except:на самом деле медленнее , чем регулярные выражения. Для строк действительных чисел, регулярное выражение медленнее. Таким образом, соответствующий метод зависит от входного сигнала.

Если вы обнаружите , что вы находитесь в безвыходной производительности, вы можете использовать новый модуль третьей стороны , которая называется 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: был быстр для ввода цифр, но очень медленно для недопустимого ввода
  • регулярное выражение очень эффективно, когда вход является недопустимым
  • fastnumbers выигрывает в обоих случаях
Ответил 14/08/2014 в 04:34
источник пользователем

голоса
14

Просто Мимические C #

В C # есть две различные функции, которые обрабатывают разборе скалярных значений:

  • Float.Parse ()
  • 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;

Примечание: Вы не хотите, чтобы вернуть логическое значение «False», потому что до сих пор тип значения. Никто не лучше, потому что это указывает на неисправность. Конечно, если вы хотите что-то другое вы можете изменить сбой параметр, что вы хотите.

Для того, чтобы расширить поплавок включить «разобрана ()» и «try_parse ()» вам необходимо monkeypatch класса «поплавок», чтобы добавить эти методы.

Если вы хотите уважать уже существующие функции код должен быть что-то вроде:

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

Sidenote: Я лично предпочитаю называть это обезьяна Штамповка, потому что он чувствует, как я злоупотребляя язык, когда я это делаю, но YMMV.

Применение:

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

И великий мудрец Pythonas сказал Святой Престол Sharpisus, «Все, что вы можете сделать, я могу сделать лучше, я могу сделать что-нибудь лучше, чем вы.»

Ответил 18/02/2012 в 02:35
источник пользователем

голоса
13

Я знаю, что это особенно старый, но я хотел бы добавить ответ я считаю, охватывает информацию, отсутствующую от самого высокого проголосовали ответ, что может быть очень ценным для любого, кто нашел это:

Для каждого из следующих способов связать их с числом, если вам нужен любой вход будет принято. (Предположим, что мы используем голосовые определения целых чисел, а не 0-255 и т.д.)

x.isdigit() работает хорошо для проверки, если х является целым числом.

x.replace('-','').isdigit() хорошо работает для проверки, если х является отрицательным (Check - в первой позиции).

x.replace('.','').isdigit() работает хорошо для проверки, если х является десятичной.

x.replace(':','').isdigit() работает хорошо для проверки, если х является отношением.

x.replace('/','',1).isdigit() работает хорошо для проверки, если х является дробь.

Ответил 05/01/2016 в 15:21
источник пользователем

голоса
10

Вы можете использовать строки Unicode, у них есть способ сделать только то, что вы хотите:

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

Ответил 04/03/2013 в 17:12
источник пользователем

голоса
9

Кастинг плавать и ловить ValueError, вероятно, самый быстрый способ, так как поплавок () специально предназначены только для этого. Все остальное, что требует строк синтаксического анализа (регулярные выражения, и т.д.), вероятно, будет медленнее из-за того, что он не настроен для этой операции. Мой $ 0,02.

Ответил 09/12/2008 в 21:31
источник пользователем

голоса
8

Допустим, у вас есть цифры в строке. ул = «100949» и вы хотели бы проверить, если он имеет только номера

if str.isdigit():
returns TRUE or FALSE 

isdigit документы

в противном случае ваш метод отлично работает, чтобы найти появление цифры в строке.

Ответил 13/10/2014 в 10:17
источник пользователем

голоса
7

Я хотел бы видеть , какой метод является самым быстрым. В целом лучшие и наиболее последовательные результаты были даны check_replaceфункции. Самые быстрые результаты были даны check_exceptionфункцией, но только если не было исключения уволено - то есть его код является наиболее эффективным, но накладные расходы бросать исключение довольно большие.

Пожалуйста , обратите внимание , что проверка для успешного броска является единственным методом , который является точной, например, это работает с , check_exceptionно две другие тестовые функции будут возвращать значение False для действительного поплавка:

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

Вот результаты с Python 2.7.10 на 2017 MacBook Pro 13:

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

Вот результаты с Python 3.6.5 на 2017 MacBook Pro 13:

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

Вот результаты с PyPy 2.7.13 на 2017 MacBook Pro 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
Ответил 16/01/2013 в 07:09
источник пользователем

голоса
6

Таким образом, чтобы поставить все это вместе, проверяя Nan, бесконечности и комплексных чисел (это, казалось бы, они указаны с J, а не я, то есть 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
Ответил 23/03/2012 в 17:10
источник пользователем

голоса
5

Ваш код выглядит хорошо для меня.

Может быть, вы думаете, что код «неуклюжий» из-за использования исключений? Обратите внимание, что Python программисты склонны использовать исключения свободно, когда он улучшает читаемость кода, благодаря его низкой потере производительности.

Ответил 11/12/2008 в 05:03
источник пользователем

голоса
4

Этот ответ обеспечивает шаг за шагом руководство, имеющая функцию с примерами, чтобы найти строку:

  • Положительное число
  • Положительная / отрицательная - целое число / с плавающей точкой
  • Как отказаться от «NaN» (не число) строк при проверке номера?

Проверьте , если строка является положительным целым числом

Вы можете использовать , str.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

Если вы хотите также проверить для отрицательных чисел и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

Пример Run:

>>> 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поплавок по сравнению с самим собой. Например:

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

Пример Run:

>>> 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функции , которая соответствует вашим требованиям.

Ответил 11/02/2018 в 08:34
источник пользователем

голоса
4

Мне нужно, чтобы определить, является ли строка отливают в основных типов (с плавающей точкой, INT, ул 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) 
Ответил 03/07/2014 в 18:12
источник пользователем

голоса
4

Я сделал некоторые испытания скорости. Допустим , что если строка скорее всего будет несколько попробовать / за исключением стратегии является самым possible.If строка , вероятно , не будет рядом , и вы заинтересованы в Integer чеком, Вортс сделать некоторые испытания (isdigit плюс заголовок '-'). Если вы заинтересованы , чтобы проверить число с плавающей запятой, вы должны использовать Try / за исключением коды whitout побега.

Ответил 12/10/2010 в 08:43
источник пользователем

голоса
3

Ввода может быть следующим:

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


Общие 1-вход:

Ввод этой функции может быть все!

Находит ли цифровая данная переменная. Числовые строки состоят из необязательного знака, любое количество цифр, необязательной десятичной части и необязательной экспоненциальной части. Таким образом + 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
Ответил 06/10/2018 в 07:23
источник пользователем

голоса
3

Ryann предполагает

Если вы хотите, чтобы вернуть значение False для NaN и Inf, изменение линии х = поплавка (ов); Возвращение (х == х) и (х - 1 = х). Это должно вернуть Справедливо для всех поплавков, кроме Inf и NaN

Но это не совсем работает, потому что при достаточно больших поплавков, x-1 == xвозвращает истину. Например,2.0**54 - 1 == 2.0**54

Ответил 29/07/2013 в 15:08
источник пользователем

голоса
1

Я также использовал функцию, которую вы упомянули, но вскоре я заметил, что строки, как «Нан», «Inf», и это изменение рассматривается как число. Поэтому я предлагаю вам улучшенную версию вашей функции, которая будет возвращать ложь на тех, типе входа и не подведет «1E3» варианта:

def is_float(text):
    try:
        float(text)
        # check for nan/infinity etc.
        if text.isalpha():
            return False
        return True
    except ValueError:
        return False
Ответил 15/10/2016 в 21:11
источник пользователем

голоса
1

Вы можете использовать регулярное выражение.

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")
Ответил 23/08/2015 в 13:22
источник пользователем

голоса
1

Попробуй это.

 def is_number(var):
    try:
       if var == int(var):
            return True
    except Exception:
        return False
Ответил 30/05/2015 в 17:12
источник пользователем

голоса
1

Я работал над проблемой, которая привела меня к этой теме, а именно, как преобразовать коллекцию данных в строки и числа в наиболее интуитивно понятным способом. Я понял, после прочтения оригинального кода, что мне нужно было иначе в двух отношениях:

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
Ответил 09/11/2014 в 14:06
источник пользователем

голоса
1

Вот мой простой способ сделать это. Допустим, что я перекручивание через несколько строк, и я хочу, чтобы добавить их в массив, если они оказываются число.

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

Заменить myvar.apppend с любой операцией вы хотите сделать со строкой, если она оказывается рядом. Идея заключается в том, чтобы попытаться использовать операции с плавающей точкой () и использовать возвращаемую ошибку, чтобы определить, является ли строка числа.

Ответил 16/07/2009 в 18:45
источник пользователем

голоса
1

Если вы хотите знать , если вся строка может быть представлена в виде числа вы будете использовать регулярное выражение (или , возможно , конвертировать поплавок обратно в строку и сравнить ее с исходной строки, но я предполагаю , что это не очень быстро ).

Ответил 10/12/2008 в 10:15
источник пользователем

голоса
0

Этот код обрабатывает экспонент, поплавки и целые числа, wihtout с помощью регулярных выражений.

return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False
Ответил 16/12/2018 в 07:12
источник пользователем

голоса
0
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
Ответил 02/08/2018 в 11:06
источник пользователем

голоса
0

использовать следующий он обрабатывает все случаи: -

import re
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3') 
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '.3')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3sd')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3')
Ответил 24/02/2017 в 11:11
источник пользователем

голоса
0

Для того, чтобы проверить , если значение входного сигнала является float, вы можете сравнить тип ввода к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а не просто номер, вы должны учитывать тот случай.

Ответил 16/09/2016 в 05:00
источник пользователем

голоса
0

Вы можете обобщить метод исключения в полезном способе, возвращая более полезные значения, чем истина и ложь. Например, эта функция помещает кавычки вокруг строк, но оставляет номера один. Какие именно то, что мне нужно для быстрого и грязного фильтра, чтобы сделать некоторые определения переменных для 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:]), ')'
Ответил 24/05/2013 в 22:36
источник пользователем

голоса
-1

У меня аналогичная проблема. Вместо того, чтобы определить функцию IsNumber, я хочу, чтобы преобразовать список строк в поплавки, то, что с точки зрения высокого уровня будет:

[ float(s) for s in list if isFloat(s)]

Это данность, мы не можем отделить поплавок (ы) из функций isFloat (s): эти два результата должны быть возвращены на ту же функцию. Кроме того, если поплавок (s) выходит из строя, весь процесс не удается, вместо того, чтобы просто игнорируя неисправный элемент. Кроме того, «0» является допустимым числом и должны быть включены в список. При фильтрации плохих элементов, быть уверенным, чтобы не исключать 0.

Таким образом, выше понимание должно быть изменено каким-то образом, чтобы:

  • если какой-либо элемент в списке не может быть преобразован, игнорировать его и не сгенерирует исключение
  • избегать вызова с плавающей точкой (ы) более, чем один раз для каждого элемента (один для преобразования, а другой для испытания)
  • если преобразованное значение равно 0, то все равно должно присутствовать в окончательном списке

Я предлагаю решение вдохновило в Nullable численных типов C #. Эти типы внутренне представлены структуры, которая имеет числовое значение и добавляет логическое значение, указывающее, если значение является действительным:

def tryParseFloat(s):
    try:
        return(float(s), True)
    except:
        return(None, False)

tupleList = [tryParseFloat(x) for x in list]
floats = [v for v,b in tupleList if b]
Ответил 18/03/2018 в 00:18
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more