Каков наилучший способ проверить, может ли строка представляться как число в Python?
У меня сейчас есть функция:
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
Который, не только уродлив и медлителен, кажется неуклюжим. Однако я не нашел лучшего метода, потому что вызов float
в главной функции еще хуже.
python
casting
floating-point
type-conversion
Даниэль Голдберг
источник
источник
x = float('0.00'); if x: use_float(x);
теперь у вас есть ошибка в вашем коде. Истинные значения являются причиной, по которой эти функции вызывают исключение, а не возвращаютсяNone
в первую очередь. Лучшее решение состоит в том, чтобы просто избегать использования служебной функции и заключать вызов в плавающее положение,try catch
когда вы хотите ее использовать.Ответы:
Я бы оспорил оба.
Регулярное выражение или другой метод синтаксического анализа строк будет более уродливым и медленным.
Я не уверен, что все может быть быстрее, чем выше. Вызывает функцию и возвращает. Try / Catch не создает больших накладных расходов, поскольку наиболее распространенное исключение перехватывается без расширенного поиска кадров стека.
Проблема в том, что любая функция преобразования чисел имеет два вида результатов
C (в качестве примера) взломает это несколькими способами. Python излагает это ясно и явно.
Я думаю, что ваш код для этого идеально подходит.
источник
try
, поэтому я бы поставилreturn True
вelse
предложении условиеtry
. Одна из причин заключается в том, что с кодом в вопросе, если бы мне пришлось его просматривать, мне пришлось бы проверить, что второе утверждение вtry
предложении не может вызвать ValueError: предоставлено, это не требует слишком много времени или умственных способностей, но зачем использовать, когда ничего не нужно?IsNumeric()
я получаю try / catch или другую упаковку try / catch. Тьфуif is_number(s): x = float(x) else: // fail
это то же количество строк кода, что иtry: x = float(x) catch TypeError: # fail
. Эта служебная функция является совершенно ненужной абстракцией.Если вы ищете синтаксические (положительные, беззнаковые) целые числа вместо плавающих, вы можете использовать эту
isdigit()
функцию для строковых объектов.Строковые методы -
isdigit()
: Python2 , Python3Есть также кое-что о строках Unicode, с которыми я не слишком знаком с Unicode - является десятичным / десятичным
источник
isdigit()
иint()
имеют разные мнения о том, что такое целое число, например, для символа Unicodeu'\u00b9'
:u'¹'.isdigit()
is,True
ноint(u'¹')
вызывает ValueError.TL; DR Лучшее решение
s.replace('.','',1).isdigit()
Я сделал несколько тестов, сравнивая различные подходы
Если строка не является числом, блок исключений работает довольно медленно. Но что еще более важно, метод try-исключения является единственным подходом, который правильно обрабатывает научные записи.
Нотация с плавающей точкой ".1234" не поддерживается:
- is_number_regex
Научная запись "1.000000e + 50" не поддерживается:
- is_number_regex
- is_number_repl_isdigit
Научная запись "1e50" не поддерживается:
- is_number_regex
- is_number_repl_isdigit
РЕДАКТИРОВАТЬ: результаты тестов
где были протестированы следующие функции
источник
s.replace('.','',1).isdigit()
) должно появиться в начале этого ответа. В любом случае это должен быть принятый. Спасибо!'1.5e-9'
или с негативами.Есть одно исключение, которое вы можете принять во внимание: строка «NaN»
Если вы хотите, чтобы is_number возвращал FALSE для 'NaN', этот код не будет работать, поскольку Python преобразует его в представление числа, которое не является числом (поговорим о проблемах идентификации):
В противном случае мне следует поблагодарить вас за фрагмент кода, который я сейчас активно использую. :)
Г.
источник
NaN
может быть хорошим значением для возврата (а неFalse
), если переданный текст на самом деле не является представлением числа. Проверять это довольно сложно (float
тип Python действительно нуждается в методе для этого), но вы можете использовать его в вычислениях, не вызывая ошибки, и нужно только проверить результат.'inf'
. Либоinf
илиNaN
может быть также с префиксом+
или-
и до сих пор принимаются.x-1 == x
верно для больших поплавков меньше, чемinf
. В Python 3.2 вы можете использоватьmath.isfinite
для проверки числа, которые не являются ни NaN, ни бесконечными, либо проверять и то,math.isnan
и другоеmath.isinf
.как насчет этого:
который вернет true, только если есть один или нет '.' в строке цифр.
вернет ложь
редактировать: только что увидел еще один комментарий ... можно добавить
.replace(badstuff,'',maxnum_badstuff)
для других случаев. если вы передаете соль, а не произвольные приправы (ref: xkcd # 974 ), это подойдет: Pисточник
1.234e56
(которые также могут быть записаны как+1.234E+56
и еще несколько вариантов).re.match(r'^[+-]*(0[xbo])?[0-9A-Fa-f]*\.?[0-9A-Fa-f]*(E[+-]*[0-9A-Fa-f]+)$', 'str')
следует лучше определить число (но не все, я не претендую на это). Я не рекомендую использовать это, гораздо лучше использовать оригинальный код Вопросника.Может потребоваться некоторое привыкание, но это питонский способ сделать это. Как уже указывалось, альтернативы хуже. Но есть еще одно преимущество таких вещей: полиморфизм.
Основная идея печатания утки заключается в том, что «если она ходит и говорит как утка, то это утка». Что, если вы решите, что вам нужно разбить строку на подклассы, чтобы вы могли изменить способ определения, может ли что-то быть преобразовано в число с плавающей точкой? Или что, если вы решите полностью протестировать какой-то другой объект? Вы можете делать эти вещи без необходимости изменения вышеуказанного кода.
Другие языки решают эти проблемы с помощью интерфейсов. Я сохраню анализ того, какое решение лучше для другого потока. Дело, однако, в том, что python решительно относится к типу уравнения утки, и вам, вероятно, придется привыкнуть к такому синтаксису, если вы планируете много программировать на Python (но это не означает, что тебе это должно нравиться конечно).
Вы можете принять во внимание еще одну вещь: Python довольно быстро генерирует и перехватывает исключения по сравнению со многими другими языками (например, в 30 раз быстрее, чем .Net). Черт, сам язык даже генерирует исключения, чтобы сообщать о неисключительных, нормальных условиях программы (каждый раз, когда вы используете цикл for). Таким образом, я не буду слишком сильно беспокоиться о производительности этого кода, пока вы не заметите существенную проблему.
источник
hasattr()
это простоgetattr()
вызов, заключенный в atry/except
. Тем не менее, обработка исключений медленнее, чем обычное управление потоком, поэтому использование его для чего-то, что должно быть верным большую часть времени, может привести к снижению производительности.Обновлен после того, как Alfe указал, что вам не нужно проверять поплавок отдельно, поскольку сложные обрабатывают оба:
Ранее сказано: В некоторых редких случаях вам также может понадобиться проверить комплексные числа (например, 1 + 2i), которые не могут быть представлены с плавающей точкой:
источник
float()
и просто проверить, чтобыcomplex()
звонок был успешным. Все проанализированныеfloat()
могут быть проанализированыcomplex()
.complex('(01989)')
вернется(1989+0j)
. Но неfloat('(01989)')
получится. Поэтому я думаю, что использованиеcomplex
не очень хорошая идея.Для
int
использования этого:Но для
float
нас нужны некоторые хитрости ;-). Каждый номер с плавающей точкой имеет одну точку ...Также для отрицательных чисел просто добавьте
lstrip()
:И теперь мы получаем универсальный способ:
источник
1.234e56
и похожие. Кроме того, мне было бы интересно, как вы узнаете, что99999999999999999999e99999999999999999999
это не число. Пытаясь разобрать это выясняется быстро.Просто Mimic C #
В C # есть две разные функции, которые обрабатывают разбор скалярных значений:
float.parse ():
Примечание. Если вам интересно, почему я изменил исключение на TypeError, вот документация .
float.try_parse ():
Примечание. Вы не хотите возвращать логическое «False», потому что это все еще тип значения. Нет лучше, потому что это указывает на неудачу. Конечно, если вы хотите что-то другое, вы можете изменить параметр сбоя на любой другой.
Чтобы расширить float для включения 'parse ()' и 'try_parse ()', вам нужно monkeypatch класс 'float', чтобы добавить эти методы.
Если вы хотите соблюдать существующие функции, код должен выглядеть примерно так:
SideNote: Я лично предпочитаю называть это Monkey Punching, потому что мне кажется, что я злоупотребляю языком, когда делаю это, но YMMV.
Применение:
И великий мудрец Питонас сказал Святейшему Престолу Шарпису: «Все, что ты можешь сделать, я могу делать лучше, я могу делать все лучше тебя».
источник
!
вместоnot
может быть незначительной ошибкой, но вы определенно не можете назначить атрибуты встроенномуfloat
в CPython.Для строк не чисел,
try: except:
на самом деле медленнее, чем регулярные выражения. Для строк действительных чисел регулярное выражение медленнее. Таким образом, соответствующий метод зависит от вашего ввода.Если вы обнаружите, что находитесь в привязке к производительности, вы можете использовать новый сторонний модуль под названием fastnumbers, который предоставляет функцию isfloat . Полное раскрытие, я автор. Я включил его результаты в сроки ниже.
Как вы видете
try: except:
был быстрым для числового ввода, но очень медленным для неверного вводаfastnumbers
выигрывает в обоих случаяхисточник
prep_code_basis
иprep_code_re_method
предотвратило бы мою ошибку.isfloat
функции?str(s).strip('-').replace('.','',1).isdigit()
это примерно в 10 раз медленнее!Я знаю, что это особенно старо, но я хотел бы добавить ответ, который, как мне кажется, охватывает информацию, отсутствующую в ответе с наибольшим количеством голосов, который может быть очень ценным для любого, кто найдет это:
Для каждого из следующих методов соедините их со счетчиком, если вам нужно принять какие-либо данные. (Предполагая, что мы используем голосовые определения целых чисел, а не 0-255 и т. Д.)
x.isdigit()
хорошо работает для проверки, если х является целым числом.x.replace('-','').isdigit()
хорошо работает для проверки, если х является отрицательным. (Проверка - в первой позиции)x.replace('.','').isdigit()
хорошо работает для проверки, если х является десятичным.x.replace(':','').isdigit()
хорошо работает для проверки, если х является отношением.x.replace('/','',1).isdigit()
хорошо работает для проверки, если х является дробью.источник
x.replace('/','',1).isdigit()
иначе даты, такие как 4/7/2017, будут неверно истолкованы как числа.Этот ответ предоставляет пошаговое руководство, имеющее функцию с примерами для поиска строки:
Проверьте, является ли строка положительным целым числом
Вы можете использовать,
str.isdigit()
чтобы проверить, является ли данная строка положительным целым числом.Пример результатов:
Проверить строку как положительную / отрицательную - целое число / число с плавающей запятой
str.isdigit()
возвращает,False
если строка является отрицательным числом или числом с плавающей запятой. Например:Если вы хотите также проверить наличие отрицательных целых чисел и
float
, то вы можете написать пользовательскую функцию для проверки:Пробный прогон:
Сбросить строки «NaN» (не число) при проверке числа
Вышеуказанные функции будут возвращать
True
строку «NAN» (не число), потому что для Python это допустимое число с плавающей точкой, представляющее, что это не число. Например:Чтобы проверить, является ли число «NaN», вы можете использовать
math.isnan()
как:Или, если вы не хотите импортировать дополнительную библиотеку, чтобы проверить это, вы можете просто проверить ее, сравнив ее с самой собой, используя
==
. Python возвращается,False
когдаnan
float сравнивается с самим собой. Например:Следовательно, выше функция
is_number
может быть обновлен , чтобы вернутьсяFalse
к"NaN"
качестве:Пробный прогон:
PS: Каждая операция для каждой проверки в зависимости от типа номера сопровождается дополнительными издержками. Выберите версию
is_number
функции, которая соответствует вашим требованиям.источник
Приведение к float и перехват ValueError, вероятно, самый быстрый способ, поскольку float () специально предназначен именно для этого. Все остальное, требующее синтаксического анализа строк (регулярное выражение и т. Д.), Вероятно, будет медленнее из-за того, что оно не настроено для этой операции. Мои $ 0,02.
источник
Вы можете использовать строки Unicode, у них есть метод, который делает то, что вы хотите:
Или:
http://www.tutorialspoint.com/python/string_isnumeric.htm
http://docs.python.org/2/howto/unicode.html
источник
s.isdecimal()
проверяет, является лиs
строка неотрицательным целым числом.s.isnumeric()
включает в себя символы, которыеint()
отклоняет.Я хотел посмотреть, какой метод самый быстрый. В целом, лучшие и наиболее последовательные результаты были получены
check_replace
функцией. Самые быстрые результаты далиcheck_exception
функцией, но только в том случае, если не было сгенерировано исключение - это означает, что ее код является наиболее эффективным, но накладные расходы на создание исключения довольно велики.Обратите внимание, что проверка на успешное приведение является единственным методом, который является точным, например, он работает,
check_exception
но две другие тестовые функции вернут False для допустимого числа с плавающей запятой:Вот эталонный код:
Вот результаты с Python 2.7.10 на MacBook Pro 13 2017 года:
Вот результаты с Python 3.6.5 на MacBook Pro 13 2017 года:
Вот результаты с PyPy 2.7.13 на MacBook Pro 13 2017 года:
источник
Таким образом, чтобы сложить все вместе, проверяя на Nan, бесконечность и комплексные числа (казалось бы, они указаны с помощью j, а не i, то есть 1 + 2j), это приводит к:
источник
Ввод может быть следующим:
a="50"
b=50
c=50.1
d="50.1"
1-Общий ввод:
Ввод этой функции может быть любым!
Находит, является ли данная переменная числовой. Числовые строки состоят из необязательного знака, любого количества цифр, необязательной десятичной части и необязательной экспоненциальной части. Таким образом, + 0123.45e6 является допустимым числовым значением. Шестнадцатеричная (например, 0xf4c3b00c) и двоичная (например, 0b10100111001) нотация не допускается.
is_numeric функция
тестовое задание:
функция is_float
Находит, является ли данная переменная плавающей. Строки float состоят из необязательного знака, любого количества цифр, ...
тестовое задание:
что такое аст ?
2- Если вы уверены, что переменным содержимым является строка :
Использование str.isdigit () метод
3-числовой вход:
определить значение int:
обнаружить поплавок:
источник
ast
"?Я сделал тест скорости. Допустим , что если строка скорее всего будет несколько попробовать / за исключением стратегии является самым possible.If строка не вероятно , чтобы быть числом , и вы заинтересованы в Integer чеком, Вортс сделать некоторые испытания (isdigit плюс заголовок '-'). Если вы заинтересованы в проверке числа с плавающей запятой, вы должны использовать пробный / исключающий код без выхода.
источник
Мне нужно было определить, приведена ли строка к базовым типам (float, int, str, bool). Не найдя ничего в интернете, я создал это:
пример
Вы можете захватить тип и использовать его
источник
RyanN предлагает
Но это не совсем работает, потому что для достаточно больших значений типа float
x-1 == x
возвращает true. Например,2.0**54 - 1 == 2.0**54
источник
Я думаю , что ваше решение прекрасно, но это правильное выполнение регулярных выражений.
Похоже, в этих ответах есть много ненависти к регулярным выражениям, которые я считаю неоправданными, регулярные выражения могут быть достаточно чистыми, правильными и быстрыми. Это действительно зависит от того, что вы пытаетесь сделать. Первоначальный вопрос заключался в том, как можно «проверить, можно ли представить строку в виде числа (с плавающей запятой)» (согласно заголовку). Предположительно, вы захотите использовать числовое значение / значение с плавающей запятой после того, как вы проверите, что оно допустимо, и в этом случае ваши попытки / исключения имеют большой смысл. Но если по какой-то причине вы просто хотите проверить, что строка является числомтогда регулярное выражение также работает нормально, но его трудно получить правильно. Я думаю, что большинство ответов на регулярные выражения до сих пор, например, неправильно анализируют строки без целочисленной части (такой как ".7"), которая является плавающей точкой в том, что касается python. И это немного сложно проверить в одном регулярном выражении, где дробная часть не требуется. Я включил два регулярных выражения, чтобы показать это.
Это поднимает интересный вопрос о том, что такое «число». Вы включаете "inf", который является допустимым как float в python? Или вы включаете числа, которые являются «числами», но, возможно, не могут быть представлены в Python (например, числа, которые больше, чем максимум с плавающей точкой).
Есть также неясности в том, как вы анализируете числа. Например, как насчет "--20"? Это «число»? Это законный способ представлять «20»? Python позволит вам сделать «var = --20» и установить его в 20 (хотя на самом деле это потому, что он обрабатывает это как выражение), но float («- 20») не работает.
В любом случае, без дополнительной информации, вот регулярное выражение, которое, я считаю, покрывает все целые числа и числа с плавающей запятой, когда python анализирует их .
Некоторые примеры тестовых значений:
Выполнение кода сравнения в ответе @ ron-reiter показывает, что это регулярное выражение на самом деле быстрее, чем обычное регулярное выражение, и намного быстрее при обработке неверных значений, чем исключение, что имеет некоторый смысл. Результаты:
источник
источник
1e6
чтобы представлять число?Вот мой простой способ сделать это. Допустим, я перебираю некоторые строки и хочу добавить их в массив, если они окажутся числами.
Замените myvar.apppend любой операцией, которую вы хотите выполнить со строкой, если она окажется числом. Идея состоит в том, чтобы попытаться использовать операцию float () и использовать возвращенную ошибку, чтобы определить, является ли строка числом.
источник
Я также использовал функцию, которую вы упомянули, но вскоре я заметил, что строки как «Nan», «Inf» и их вариация считаются числом. Поэтому я предлагаю вам улучшенную версию вашей функции, которая будет возвращать false при вводе такого типа и не потерпит неудачу в вариантах «1e3»:
источник
Этот код обрабатывает экспоненты, числа с плавающей точкой и целые числа без использования регулярных выражений.
источник
Пользовательская вспомогательная функция:
тогда
источник
Вы можете обобщить технику исключений полезным способом, возвращая больше полезных значений, чем True и False. Например, эта функция помещает кавычки в круглые строки, но оставляет числа в покое. Это как раз то, что мне нужно для быстрого и грязного фильтра, чтобы сделать некоторые определения переменных для R.
источник
Я работал над проблемой, которая привела меня к этой теме, а именно, как преобразовать коллекцию данных в строки и числа наиболее интуитивным способом. После прочтения исходного кода я понял, что то, что мне было нужно, отличалось двумя способами:
1 - я хотел получить целочисленный результат, если строка представляла целое число
2 - я хотел, чтобы число или строковый результат прилипали к структуре данных
поэтому я адаптировал исходный код для получения этой производной:
источник
Попробуй это.
источник
is_number('10')
источник