检查字符串是否可以用Python表示为数字的最佳方法是什么?
我目前的功能是:
1 2 3 4 5 6 | def is_number(s): try: float(s) return True except ValueError: return False |
这不仅又丑又慢,而且显得笨拙。然而,我还没有找到更好的方法,因为在主函数中调用
如果您正在寻找解析(正的、无符号的)整数而不是浮点数,您可以对字符串对象使用
1 2 3 4 5 6 | >>> a ="03523" >>> a.isdigit() True >>> b ="963spam" >>> b.isdigit() False |
字符串方法-
Unicode字符串也有一些我不太熟悉的东西Unicode—是decimal/decimal
Which, not only is ugly and slow
我争论。
正则表达式或其他字符串解析将更难看、更慢。
我不确定是否还有比上面更快的速度。它调用函数并返回。Try/Catch不会带来太多开销,因为最常见的异常是在没有对堆栈帧进行广泛搜索的情况下捕获的。
问题是,任何数值转换函数都有两种结果
一个数字,如果这个数字是有效的状态码(例如,通过errno)或异常,表明不能解析任何有效数字。C(举个例子)用了很多方法来解决这个问题。Python清楚而明确地列出了它。
我认为您这样做的代码是完美的。
最好的解决方案是
我做了一些基准测试来比较不同的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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() |
如果字符串不是一个数字,exception -block会非常慢。但更重要的是,try-except方法是正确处理科学符号的唯一方法。
1 2 3 4 5 6 7 8 9 10 11 12 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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
编辑:基准测试结果1 2 3 4 5 6 7 8 9 10 11 | 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))) |
下列功能是在哪里测试的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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() |
您可能需要考虑一个例外:字符串"NaN"
如果你想让is_number返回FALSE for 'NaN',这段代码将不起作用,因为Python把它转换成它表示的不是数字的数字(讨论身份问题):
1 2 | >>> float('NaN') nan |
否则,我应该感谢您现在广泛使用的代码。:)
G。
这个怎么样:
1 | '3.14'.replace('.','',1).isdigit() |
只有当有或没有时,才会返回true。"在一串数字中。
1 | '3.14.5'.replace('.','',1).isdigit() |
将返回错误
编辑:刚刚看到另一条评论……可以为其他情况添加
更新后,Alfe指出,你不需要检查浮动分别作为复杂的处理两个:
1 2 3 4 5 6 7 | def is_number(s): try: complex(s) # for int, long, float and complex except ValueError: return False return True |
前面说过:在一些罕见的情况下,你可能还需要检查复数(例如1+2i),它不能用浮点数表示:
1 2 3 4 5 6 7 8 9 10 | 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 |
Which, not only is ugly and slow, seems clunky.
这可能需要一些时间来适应,但这是python的方法。正如已经指出的那样,其他选择更糟。但是这样做还有一个好处:多态性。
鸭子打字的核心思想是"如果它像鸭子一样走路和说话,那么它就是一只鸭子。"如果您决定需要子类化string,以便更改如何确定是否可以将某些内容转换为浮点数,该怎么办?或者如果您决定完全测试其他对象呢?您可以在不更改上述代码的情况下完成这些操作。
其他语言通过使用接口来解决这些问题。我将把哪个解决方案更好的分析留给另一个线程。不过,重点是python显然是在等式的鸭子类型那一边,如果您打算用python进行大量编程,那么您可能必须习惯这样的语法(当然,这并不意味着您必须喜欢它)。
另一件您可能需要考虑的事情是:与许多其他语言相比,Python在抛出和捕获异常方面非常快(例如,比. net快30倍)。糟糕的是,语言本身甚至抛出异常来通信非异常的正常程序条件(每次使用for循环时)。因此,在您注意到一个重要问题之前,我不会过多地担心这段代码的性能方面。
对于
1 2 | >>>"1221323".isdigit() True |
但是对于
1 2 3 4 5 6 | >>>"12.34".isdigit() False >>>"12.34".replace('.','',1).isdigit() True >>>"12.3.4".replace('.','',1).isdigit() False |
同样对于负数,只需添加
1 2 | >>> '-12'.lstrip('-') '12' |
现在我们有一个普遍的方法:
1 2 3 4 | >>> '-12.34'.lstrip('-').replace('.','',1).isdigit() True >>> '.-234'.lstrip('-').replace('.','',1).isdigit() False |
对于非数字字符串,
如果发现自己的性能受到限制,可以使用一个名为fastnumbers的第三方模块,该模块提供一个名为isfloat的函数。完全披露,我是作者。我已经将它的结果包含在下面的计时中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 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() |
1 2 3 4 5 6 7 8 9 10 11 | 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 |
大家可以看到
只是模仿c#
在c#中有两个不同的函数来处理标量值的解析:
Float.Parse ()Float.TryParse ()float.parse ():
1 2 3 4 5 | def parse(string): try: return float(string) except Exception: throw TypeError |
注意:如果您想知道为什么我将异常更改为一个TypeError,这里是文档。
float.try_parse ():
1 2 3 4 5 | def try_parse(string, fail=None): try: return float(string) except Exception: return fail; |
注意:您不希望返回boolean 'False',因为它仍然是值类型。没有比这更好的了,因为这意味着失败。当然,如果您想要一些不同的东西,您可以将fail参数更改为您想要的任何值。
要扩展float以包含'parse()'和'try_parse()',您需要monkeypatch 'float'类来添加这些方法。
如果你想尊重已有的功能,代码应该是这样的:
1 2 3 4 5 | def monkey_patch(): if(!hasattr(float, 'parse')): float.parse = parse if(!hasattr(float, 'try_parse')): float.try_parse = try_parse |
SideNote:我个人更喜欢称之为Monkey Punching,因为当我这样做的时候,我感觉我在滥用语言,但是YMMV。
用法:
1 2 3 4 | 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 |
伟大的圣人毕达纳对夏皮修斯说:"你能做的任何事,我都能做得更好;我能做的比你更好。"
我知道这是一个特别古老的问题,但我想补充一个我认为涵盖了最高投票答案中缺失的信息的答案,这对任何发现这一点的人都是非常有价值的:
对于下面的每个方法,如果需要接受任何输入,请将它们与计数连接起来。(假设我们使用的是整数的口头定义,而不是0-255,等等)
你可以使用Unicode字符串,他们有一个方法做你想做的:
1 2 3 | >>> s = u"345" >>> s.isnumeric() True |
或者:
1 2 3 4 | >>> s ="345" >>> u = unicode(s) >>> u.isnumeric() True |
http://www.tutorialspoint.com/python/string_isnumeric.htm
http://docs.python.org/2/howto/unicode.html
强制转换为float并捕获ValueError可能是最快的方法,因为float()专门针对这一点。任何其他需要字符串解析(regex等)的操作都可能会比较慢,因为它没有针对这个操作进行调优。我的0.02美元。
我想看看哪种方法最快。总的来说,
请注意,检查一个成功的转换是唯一的方法,这是准确的,例如,这与
1 | huge_number = float('1e+100') |
以下是基准代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 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年MacBook Pro 13搭载Python 2.7.10的结果:
1 2 3 4 5 6 7 8 9 | 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年MacBook Pro 13搭载Python 3.6.5的测试结果:
1 2 3 4 5 6 7 8 9 | 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年MacBook Pro 13搭载PyPy 2.7.13的结果:
1 2 3 4 5 6 7 8 9 | 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 |
这个答案提供了一步一步的指南,有函数的例子,以找到字符串是:
正整数正/负-整数/浮动如何在检查数字时丢弃"NaN"(不是数字)字符串?检查字符串是否为正整数您可以使用
结果:样本
1 2 3 4 5 | # For digit >>> '1'.isdigit() True >>> '1'.isalpha() False |
检查字符串是否为正/负整数/浮点数
如果字符串是负数或浮点数,则
1 2 3 4 5 6 | # returns `False` for float >>> '123.3'.isdigit() False # returns `False` for negative number >>> '-123'.isdigit() False |
如果你也想检查负整数和
1 2 3 4 5 6 7 8 | 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 |
示例运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | >>> 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"(不是数字)字符串
上面的函数将为"NAN"(不是数字)字符串返回
1 2 | >>> is_number('NaN') True |
为了检查数字是否为"NaN",您可以使用
1 2 3 4 5 | >>> import math >>> nan_num = float('nan') >>> math.isnan(nan_num) True |
或者如果您不想导入额外的库来检查这个,那么您可以通过使用
1 2 3 | # `nan_num` variable is taken from above example >>> nan_num == nan_num False |
因此,可以将上述函数
1 2 3 4 5 6 7 8 9 | 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 |
示例运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | >>> 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:根据数字的类型,每次检查的每个操作都有额外的开销。选择适合您需求的
假设字符串中有数字。str =" 100949"你想要检查它是否只有数字
1 2 | if str.isdigit(): returns TRUE or FALSE |
isdigit文档
否则,您的方法可以很好地查找字符串中出现的数字。
所以把它们放在一起,检查Nan、∞和复数(看起来它们是用j而不是i指定的,即1+2j),结果是:
1 2 3 4 5 6 7 8 9 10 | 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 |
我觉得你的代码很好。
也许您认为代码"笨拙"是因为使用异常?请注意,Python程序员倾向于在提高代码可读性时大量使用异常,这要感谢它的低性能损失。
我需要确定一个字符串是否转换为基本类型(float、int、str、bool)。在网上找不到任何东西后,我创建了这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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) |
例子
1 2 3 4 5 | 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 |
您可以捕获类型并使用它
1 2 3 | s ="6.0" type_ = str_to_type(s) # float f = type_(s) |
我做了一些速度测试。假设字符串可能是一个数字,try/except策略是最快的。如果字符串不太可能是一个数字,而您对整数检查感兴趣,那么有必要做一些测试(isdigit加上标题"-")。如果您对检查浮点数感兴趣,则必须使用try/except代码whitout转义。
输入内容如下:
1输入:
这个函数的输入可以是任何东西!
查找给定变量是否为数值。数字串由可选符号、任意位数、可选小数部分和可选指数部分组成。因此+0123.45e6是一个有效的数值。不允许十六进制(例如0xf4c3b00c)和二进制(例如0b10100111001)表示法。
is_numeric函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 |
测试:
1 2 3 4 5 6 | >>> is_numeric("54") True >>> is_numeric("54.545") True >>> is_numeric("0x45") True |
is_float函数
查找给定变量是否为浮点数。浮点字符串由可选符号、任意数字、…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 |
测试:
1 2 3 4 5 6 7 8 9 10 | >>> is_float("5.4") True >>> is_float("5") False >>> is_float(5) False >>> is_float("5") False >>> is_float("+5.4") True |
ast是什么?
2-如果您确信变量内容是String:使用str.isdigit()方法
1 2 3 4 5 6 7 8 | >>> 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-Numerical输入:
检测int值:
1 2 3 4 5 | >>> isinstance("54", int) False >>> isinstance(54, int) True >>> |
检测浮动:
1 2 3 4 | >>> isinstance("45.1", float) False >>> isinstance(45.1, float) True |
RyanN建议
If you want to return False for a NaN and Inf, change line to x = float(s); return (x == x) and (x - 1 != x). This should return True for all floats except Inf and NaN
但这并不完全有效,因为对于足够大的浮点数,
我也使用了你提到的函数,但很快我注意到字符串"Nan","Inf",它的变化被认为是数字。所以我建议你改进你的函数版本,这将返回false对那些类型的输入,不会失败的"1e3"变种:
1 2 3 4 5 6 7 8 9 | def is_float(text): try: float(text) # check for nan/infinity etc. if text.isalpha(): return False return True except ValueError: return False |
这段代码使用正则表达式处理指数、浮点数和整数。
1 | return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False |
我正在研究一个问题,这个问题让我想到了这个线程,即如何以最直观的方式将数据集合转换为字符串和数字。在阅读了原始代码后,我意识到我需要的东西在两个方面是不同的:
1 -我想要一个整数的结果,如果字符串表示一个整数
2 -我想要一个数字或字符串的结果坚持到一个数据结构
所以我修改了原始代码来生成这个导数:
1 2 3 4 5 6 7 8 9 10 | def string_or_number(s): try: z = int(s) return z except ValueError: try: z = float(s) return z except ValueError: return s |
试试这个。
1 2 3 4 5 6 | def is_number(var): try: if var == int(var): return True except Exception: return False |
这是我的简单方法。假设我在循环一些字符串如果它们是数字,我想把它们添加到数组中。
1 2 3 4 | try: myvar.append( float(string_to_check) ) except: continue |
取代myvar一样。如果字符串是一个数字,apppend可以使用您想对它执行的任何操作。其思想是尝试使用float()操作并使用返回的错误来确定字符串是否是一个数字。
如果您想知道是否可以将整个字符串表示为一个数字,那么您将需要使用regexp(或者将浮点数转换回一个字符串,并将其与源字符串进行比较,但我猜这并不快)。
通过返回比True和False更有用的值,可以以一种有用的方式概括异常技术。例如,这个函数将引号放在字符串的周围,但保留数字。这正是我所需要的一个快速和肮脏的过滤器,使一些变量定义R。
1 2 3 4 5 6 7 8 9 10 11 12 | 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:]), ')' |
使用以下它处理所有的情况:-
1 2 3 4 5 6 | 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') |
我也有类似的问题。我不想定义isNumber函数,我想把字符串列表转换成浮点数,用高级术语来说就是:
1 | [ float(s) for s in list if isFloat(s)] |
假设我们不能将浮点数与isFloat函数真正分开:这两个结果应该由同一个函数返回。此外,如果float(s)失败,整个进程就会失败,而不是忽略有错误的元素。另外,"0"是一个有效的数字,应该包含在列表中。当过滤掉不好的元素时,一定不要排除0。
因此,上述理解必须修改为:
如果列表中的任何元素无法转换,请忽略它,不要抛出异常避免为每个元素(一个用于转换,另一个用于测试)多次调用float(s)如果转换后的值为0,它应该仍然出现在最终列表中我在c#的可空数值类型中提出了一个解决方案。这些类型在内部由一个结构体表示,该结构体具有数值,并添加一个布尔值,指示该值是否有效:
1 2 3 4 5 6 7 8 | 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] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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 |