从带有空格的字符串解析 int 不同于 py2 到 py3
Parsing int from string with whitespace differs from py2 to py3
将带空格的字符串解析为整数已从 Python2 更改为 Python3。
在Python2中是:
>>> int('-11')
-11
>>> int('- 11')
-11
而在 Python3 中:
>>> int('-11')
-11
>>> int('- 11')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '- 11'
弄清楚这一点后,我试图在文档中找到有关此更改的一些解释 for/elaborations,但找不到任何内容。
所以我的问题是:如何修改代码从py2迁移到py3? i = int(s.replace(' ',''))
是正确的选择吗?或者有更好的建议吗?是否有一些我只是没有找到的关于该更改的描述?
在 Python 3 中似乎字符串文字中的空格没有被丢弃,但是,Python 解析器仍然忽略在数字文字中发现的空格:
>>> e = - 11
>>> e
-11
因此,您可以在 Python 2 和 3 中直接在输入字符串上使用 ast.literal_eval
,因此忽略空格:
>>> import ast
>>> ast.literal_eval('- 11 ')
-11
无需重新发明轮子。对于 PY2 && PY3
import re
int(re.sub(r'[^\d\-]', '', '- 11'))
测试
>>> int(re.sub(r'[^\d\.\-]', '', '- 11'))
-11
>>> int(re.sub(r'[^\d\.\-]', '', '+ 11'))
11
>>> int(re.sub(r'[^\d\.\-]', '', '+ 11easd'))
11
>>> int(re.sub(r'[^\d\.\-]', '', '+ 11easd3325'))
113325
这已在 Python 3 中明确更改,以响应 issue 1779:
I discovered that when converting a string to an int or float, the int
conversion allows whitespace after the sign, while the float conversion
doesn't. I think they should be consistent.
这已在 3.0a3 changelog 中注明(问题编号中有错字):
- Issue #1769: Now int("- 1") is not allowed any more.
允许空格与其他数字转换不一致。
解决此问题的最快方法是使用 str.replace()
,是的:
>>> import timeit
>>> timeit.timeit('int("- 1".replace(" ", ""))')
0.37510599600500427
>>> timeit.timeit('int("- 1".translate(map))', 'map = {32: None}')
0.45536769900354557
>>> timeit.timeit('literal_eval("- 1")', 'from ast import literal_eval')
6.255796805999125
>>> timeit.timeit('int(extract("- 1"))', 'import re; from functools import partial; extract = partial(re.compile(r"[^\d\.\-]").sub, "")')
0.7367695900029503
Python 2.7 文档 was updated after the fact,通过向后移植 Python 3 文档。它现在明确指出符号和数字之间不应有空格。所以官方不再支持空格,但为了不破坏向后兼容性,这个错误被留在了。
将带空格的字符串解析为整数已从 Python2 更改为 Python3。
在Python2中是:
>>> int('-11')
-11
>>> int('- 11')
-11
而在 Python3 中:
>>> int('-11')
-11
>>> int('- 11')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '- 11'
弄清楚这一点后,我试图在文档中找到有关此更改的一些解释 for/elaborations,但找不到任何内容。
所以我的问题是:如何修改代码从py2迁移到py3? i = int(s.replace(' ',''))
是正确的选择吗?或者有更好的建议吗?是否有一些我只是没有找到的关于该更改的描述?
在 Python 3 中似乎字符串文字中的空格没有被丢弃,但是,Python 解析器仍然忽略在数字文字中发现的空格:
>>> e = - 11
>>> e
-11
因此,您可以在 Python 2 和 3 中直接在输入字符串上使用 ast.literal_eval
,因此忽略空格:
>>> import ast
>>> ast.literal_eval('- 11 ')
-11
无需重新发明轮子。对于 PY2 && PY3
import re
int(re.sub(r'[^\d\-]', '', '- 11'))
测试
>>> int(re.sub(r'[^\d\.\-]', '', '- 11'))
-11
>>> int(re.sub(r'[^\d\.\-]', '', '+ 11'))
11
>>> int(re.sub(r'[^\d\.\-]', '', '+ 11easd'))
11
>>> int(re.sub(r'[^\d\.\-]', '', '+ 11easd3325'))
113325
这已在 Python 3 中明确更改,以响应 issue 1779:
I discovered that when converting a string to an int or float, the int conversion allows whitespace after the sign, while the float conversion doesn't. I think they should be consistent.
这已在 3.0a3 changelog 中注明(问题编号中有错字):
- Issue #1769: Now int("- 1") is not allowed any more.
允许空格与其他数字转换不一致。
解决此问题的最快方法是使用 str.replace()
,是的:
>>> import timeit
>>> timeit.timeit('int("- 1".replace(" ", ""))')
0.37510599600500427
>>> timeit.timeit('int("- 1".translate(map))', 'map = {32: None}')
0.45536769900354557
>>> timeit.timeit('literal_eval("- 1")', 'from ast import literal_eval')
6.255796805999125
>>> timeit.timeit('int(extract("- 1"))', 'import re; from functools import partial; extract = partial(re.compile(r"[^\d\.\-]").sub, "")')
0.7367695900029503
Python 2.7 文档 was updated after the fact,通过向后移植 Python 3 文档。它现在明确指出符号和数字之间不应有空格。所以官方不再支持空格,但为了不破坏向后兼容性,这个错误被留在了。