检索完整的数字

时间:2012-09-08 00:35:58

标签: python integer

假设我有一个字符串,如下所示:expression = '123 + 321'

我按字符逐个字符地遍历字符串:for p in expression。我正在检查p是否是使用p.isdigit()的数字。如果p是一个数字,我想抓住整个数字(抓住123321,而不只是p,最初是1 )。

我怎么能用Python做到这一点?

在C中(来自C背景),等价物是:

int x = 0;
sscanf(p, "%d", &x);
// the full number is now in x

修改

基本上,我接受来自用户的数学表达式,它接受正整数,+, - ,*,/以及括号:'('和')'。我逐字逐句地走字符串,我需要能够确定字符是否是数字。使用isdigit(),我可以。如果它是一个数字,我需要抓住整数。怎么办?

7 个答案:

答案 0 :(得分:3)

>>> from itertools import groupby
>>> expression = '123 + 321'
>>> expression = ''.join(expression.split()) # strip whitespace
>>> for k, g in groupby(expression, str.isdigit):
        if k: # it's a digit
            print 'digit'
            print list(g)
        else:
            print 'non-digit'
            print list(g)


digit
['1', '2', '3']
non-digit
['+']
digit
['3', '2', '1']

答案 1 :(得分:2)

这是可以从许多不同方向处理的问题之一。以下是我认为基于itertools.takewhile的优雅解决方案:

>>> from itertools import chain, takewhile
>>> def get_numbers(s):
...     s = iter(s)
...     for c in s:
...         if c.isdigit():
...             yield ''.join(chain(c, takewhile(str.isdigit, s)))
... 
>>> list(get_numbers('123 + 456'))
['123', '456']

这甚至适用于列表理解:

>>> def get_numbers(s):
...     s = iter(s)
...     return [''.join(chain(c, takewhile(str.isdigit, s)))
...             for c in s if c.isdigit()]
... 
>>> get_numbers('123 + 456')
['123', '456']

查看其他答案,我发现这与jamylakgroupby解决方案没有什么不同。我建议如果你不想丢弃额外的符号。但如果你想丢弃它们,我认为这有点简单。

答案 2 :(得分:1)

虽然我不熟悉sscanf,但我不是C开发人员,看起来它使用的格式字符串与我使用python的re模块的方式不同。像这样:

import re

nums = re.compile('\d+')
found = nums.findall('123 + 321')
# if you know you're only looking for two values.
left, right = found

答案 3 :(得分:1)

Python文档包含一个关于simulating scanf的部分,它让您了解如何使用正则表达式来模拟scanf(或sscanf的行为,它们都是相同的在Python)。特别是,r'\-?\d+'是对应于整数正则表达式的Python字符串。 (r'\d+'表示非负整数。)因此,您可以将其嵌入循环中

integer = re.compile(r'\-?\d+')
for p in expression:
    if p.isdigit():
        # somehow find the current position in the string
        integer.match(expression, curpos)

但这仍然反映了一种非常类似于C的思维方式。在Python中,你的迭代器变量p实际上只是一个单独的字符,它实际上是从原始字符串中拉出来的,并且是独立的。因此,在循环中,您自然无法访问字符串中的当前位置,并且尝试计算它将不是最优的。

我建议使用Python内置的regexp匹配迭代方法:

integer = re.compile(r'\-?\d+') # only do this once in your program

all_the_numbers = integer.findall(expression)

现在all_the_numbers是表达式中所有整数的字符串表示的列表。如果你想将它们实际转换为整数,那么你可以这样做而不是最后一行:

all_the_numbers = [int(s) for s in integer.finditer(expression)]

在这里,我使用了finditer而不是findall,因为在重新迭代它们以将它们转换为整数之前,您不必创建所有字符串的列表。

答案 4 :(得分:1)

您可以使用shlex http://docs.python.org/library/shlex.html

>>> from shlex import shlex
>>> expression = '123 + 321'
>>> for e in shlex(expression):
...     print e
... 
123
+
321

>>> expression = '(92831 * 948) / 32'
>>> for e in shlex(expression):
...     print e
... 
(
92831
*
948
)
/
32

答案 5 :(得分:0)

e_array = expression.split('+')
i_array = map(int, e_array)

i_array保存表达式中的所有整数。


更新

如果您已经知道表达式中的所有特殊字符,并且想要将它们全部删除

import re

e_array = re.split('[*/+\-() ]', expression)  # all characters here is mult, div, plus, minus, left- right- parathesis and space
i_array = map(int, filter(lambda x: len(x), e_array))

答案 6 :(得分:0)

我将字符串拆分为' + '字符串,为您提供不在其中的内容:

>>> expression = '123 + 321'
>>> ex = expression.split(' + ')
>>> ex
['123', '321']
>>> int_ex = map(int, ex)
>>> int_ex
[123, 321]
>>> sum(int_ex)
444

这很危险,但您可以使用eval

>>> eval('123 + 321')
444

我只是在解析字符串,并对其进行原始计算。