2012-09-08 90 views
2

假設我有一個字符串,如下所示:expression = '123 + 321'正在檢索完整數

我按照以下字符逐字符走過:for p in expression。我正在檢查p是否是使用p.isdigit()的數字。如果p是一個數字,我想抓住整個數字(所以抓住123321,而不僅僅是,最初將是1)。

我該怎麼用Python做到這一點?

在C(從C背景的),則相當於將是:

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

編輯:

基本上,我接受來自接受正整數的用戶的數學表達式, +, - ,*,/以及括號:'('和')'。我逐字符地走字符串,我需要能夠確定字符是否是數字。使用isdigit(),我可以。如果它是一個數字,但是我需要抓住整個數字。如何做到這一點?

+0

對於一個快速和骯髒的解決方案,請參閱'eval'我的話。完整的答案可能涉及堆棧,解析和一些數學標記。如果可能,我會用'eval'去。 – Droogans

+0

我已經在使用堆棧和解析。 – darksky

回答

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內置的正則表達式匹配迭代法:

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,因爲你沒有做的所有列表然後再次遍歷它們以將它們轉換爲整數。

+0

非常感謝!我在尋找一個答案,它描述了Python中的「自然」。我想我需要擺脫我在Python中工作時的低級C心態,因爲在Python中工作時效率並不高。 – darksky

+0

是的,這是一種很好的方法來處理Python(尋找什麼是自然的),因爲即使在Python標準庫中,也有很多功能可以爲您執行相當高級的操作。在很多方面,Python比C更「明確」 - 例如,這種風格是對事物的各個元素進行迭代,而不是對事物中的索引進行迭代。 –

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

i_array在表達式中包含所有整數。


UPDATE

如果你已經知道你表達所有的特殊字符,你想消滅他們所有

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)) 
+1

如果我事先不知道表情怎麼辦?我所知道的是我有一個正確的數學表達式。可能是:(92831 * 948)/ 32'。此刻,我正在逐字走完整個表情。 – darksky

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 

我只是採取了刺在你解析字符串,並在其上做原料計算。

+0

這可能不會對我有太大的作用,因爲我接受的用戶表達可以是他們想要的長度,並且可以包含任何正整數,+, - ,*,/以及括號(和)。 – darksky

+0

你問的不僅僅是你的問題。也許你想更新它? – Droogans

+0

已更新。抱歉。 – darksky

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

雖然我不熟悉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 
+0

正則表達式的問題在於它們有一個陡峭的學習曲線,目前我不願意真正學習它們。另外,表達對我來說是未知的。它可以是'(111 * 302)/ 32'。我需要弄清楚「p」是一個數字還是一個操作符。 – darksky

+2

@Darksky:如果你不想學習正則表達式,你正在爲痛苦的世界設置一個痛苦的字符串解析形式。你真的只需要'\ d'(數字)和一個運算符的字符類(例如'[\/* - +]')。搜索「正則表達式數學表達式」可以得到大量現成的代碼,並在SO上有很好的解釋。 – jmdeldin

+0

@Darksky:爲什麼不用C編碼?當你準備花時間學習它時,你總是可以回到Python。 –

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解決方案。我會建議如果你不想放棄額外的符號。但如果你想放棄它們,我認爲這有點簡單。

+0

出於某種原因,即使我使用了'itertools',它總是說'鏈'是不確定的。 – darksky

+0

對不起,我忘了導入線。嘗試'從itertools進口鏈,takewhie'。 – senderle

1

您可以使用shlexhttp://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