TL; DR :
- Если ваш ввод - это в основном строки, которые можно преобразовать в числа с плавающей запятой, этот
try: except:
метод - лучший собственный метод Python.
- Если ваш ввод в основном состоит из строк, которые нельзя преобразовать в числа с плавающей запятой, лучше подойдут регулярные выражения или метод разделения.
- Если вы 1) не уверены в своих вводах или вам нужно больше скорости и 2) вы не возражаете и можете установить стороннее расширение C, fastnumbers работает очень хорошо.
Есть еще один метод, доступный через сторонний модуль под названием fastnumbers (раскрытие, я являюсь автором); он предоставляет функцию isfloat . Я взял пример unittest, описанный Джейкобом Габриэльсоном в этом ответе , но добавил fastnumbers.isfloat
метод. Я также должен отметить, что в примере Джейкоба не было должного внимания к параметру регулярного выражения, потому что большая часть времени в этом примере была потрачена на глобальный поиск из-за оператора точки ... Я изменил эту функцию, чтобы дать более справедливое сравнение try: except:
.
def is_float_try(str):
try:
float(str)
return True
except ValueError:
return False
import re
_float_regexp = re.compile(r"^[-+]?(?:\b[0-9]+(?:\.[0-9]*)?|\.[0-9]+\b)(?:[eE][-+]?[0-9]+\b)?$").match
def is_float_re(str):
return True if _float_regexp(str) else False
def is_float_partition(element):
partition=element.partition('.')
if (partition[0].isdigit() and partition[1]=='.' and partition[2].isdigit()) or (partition[0]=='' and partition[1]=='.' and partition[2].isdigit()) or (partition[0].isdigit() and partition[1]=='.' and partition[2]==''):
return True
else:
return False
from fastnumbers import isfloat
if __name__ == '__main__':
import unittest
import timeit
class ConvertTests(unittest.TestCase):
def test_re_perf(self):
print
print 're sad:', timeit.Timer('ttest.is_float_re("12.2x")', "import ttest").timeit()
print 're happy:', timeit.Timer('ttest.is_float_re("12.2")', "import ttest").timeit()
def test_try_perf(self):
print
print 'try sad:', timeit.Timer('ttest.is_float_try("12.2x")', "import ttest").timeit()
print 'try happy:', timeit.Timer('ttest.is_float_try("12.2")', "import ttest").timeit()
def test_fn_perf(self):
print
print 'fn sad:', timeit.Timer('ttest.isfloat("12.2x")', "import ttest").timeit()
print 'fn happy:', timeit.Timer('ttest.isfloat("12.2")', "import ttest").timeit()
def test_part_perf(self):
print
print 'part sad:', timeit.Timer('ttest.is_float_partition("12.2x")', "import ttest").timeit()
print 'part happy:', timeit.Timer('ttest.is_float_partition("12.2")', "import ttest").timeit()
unittest.main()
На моей машине результат:
fn sad: 0.220988988876
fn happy: 0.212214946747
.
part sad: 1.2219619751
part happy: 0.754667043686
.
re sad: 1.50515985489
re happy: 1.01107215881
.
try sad: 2.40243887901
try happy: 0.425730228424
.
----------------------------------------------------------------------
Ran 4 tests in 7.761s
OK
Как видите, регулярное выражение на самом деле не так плохо, как казалось изначально, и если вам действительно нужна скорость, fastnumbers
метод вполне подойдет.