2

次のような文字列があるとします: expression = '123 + 321'.

次のように、文字列を 1 文字ずつ調べていますfor p in expressionpを使用して が数字かどうかを確認してp.isdigit()います。が数字の場合p、数字全体を取得したいと思います (したがって、最初は であるだけでなく、123とを取得します)。321p1

Pythonでそれを行うにはどうすればよいですか?

C (C のバックグラウンドから来ている) では、同等のものは次のようになります。

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

編集:

基本的に、正の整数、+、-、*、/、および括弧「(」および「)」を受け入れるユーザーからの数式を受け入れています。文字列を 1 文字ずつ調べていますが、その文字が数字かどうかを判断できる必要があります。を使用するisdigit()と、それができます。ただし、数字の場合は、整数を取得する必要があります。どうすればそれができますか?

4

7 に答える 7

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']
于 2012-09-08T00:42:14.047 に答える
2

これは、さまざまな方向からアプローチできる問題の 1 つです。これが、に基づくエレガントなソリューションだと私が思うものです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ソリューションと似ていないことがわかります。余分なシンボルを破棄したくない場合は、お勧めします。しかし、それらを破棄したい場合は、こちらの方が少し簡単だと思います。

于 2012-09-08T00:59:36.767 に答える
1

http://docs.python.org/library/shlex.htmlを使用できますshlex

>>> 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
于 2012-09-08T07:38:28.593 に答える
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
于 2012-09-08T00:44:59.433 に答える
1

Python のドキュメントには、 のシミュレートに関するセクションが含まれており、正規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 の組み込みの正規表現マッチング反復メソッドを使用することです。

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したのは、すべての文字列のリストを作成してから整数に変換する前に繰り返し処理する必要がないためです。

于 2012-09-08T00:54:07.583 に答える
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

私はあなたが文字列を解析し、それに対して生の計算を行っていることを突き刺しています。

于 2012-09-08T00:41:25.270 に答える
0
e_array = expression.split('+')
i_array = map(int, e_array)

Andi_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))
于 2012-09-08T00:39:16.453 に答える