2013-10-17 76 views
1

我希望能夠驗證括號,以便它們包圍並忽略任何類型的字符。只要有效地使用括號括起來的字符串,那麼其他的錯誤就是Truepop()邏輯中的空deque()

我還是新來的python,所以我不知道如何正確地創建一個if語句爲這個特定的條件。我想創建一個網絡聲明,這樣當我.pop()deque()我就能return False,而不是收到錯誤消息:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: pop from an empty deque 

也許周圍有解決這個問題的另一種更好的方法。如果是的話我會很高興地看到別人會解決它

例如:

a = 'sdf(sadf(sdf)sdf)sdfsd0sdf)sdf(sdf0)' # false 
b = 'dsf))))(((((dsfsdf' # false 
c = '()()()()' # true 
d = '((((asd(asd)asd)()()asd))' # true 

我的代碼:

# any letter is ignored 
# jsut make sure that the parenthesis are equal 

from collections import * 

def str_valid(stringy): 
    param_stack = deque() 
    for n in stringy: 
     if n ==')': 
      param_stack.pop() 
     if n == '(': 
      param_stack.append('(') 
    if param_stack == []: 
     return True 
    else: 
     return False 

a = 'sdf(sadf(sdf)sdf)sdfsd0sdf)sdf(sdf0)' # false 
b = 'dsf))))(((((dsfsdf' # false 
c = '()()()()' # true 
d = '((((asd(asd)asd)()()asd))' # true 

print str_valid(a) 

print str_valid(b) 

print str_valid(c) 

print str_valid(d) 
+0

爲什麼當一個簡單的整數計數器可以做到這一點時,爲什麼使用'deque'呢?從0開始,在看到'(',減少,當看到'''''時遞減',然後'不返回paren_count')。 – kindall

+0

,因爲如果你在開頭看到一個'')'''',因爲''''開始的外殼將不起作用。 – Liondancer

+1

是的,很抱歉,只要你低於零就需要失敗。但是,當你真正感興趣的是它的長度時,你仍然不需要容器。這就像在牆上寫100個標記一樣數到100。 – kindall

回答

1

如果你只是想彈出()的空雙端隊列不問題:

from collections import deque 

d = deque() 
try: 
    d.pop() 
except IndexError: 
    pass # do whatever you want in the case that there is nothing there 
    return False # is this what you want? 
else: 
    pass # do whatever you want in the case that there is something there 

只是一個警告,如果你不知道:保持try/except/else/try儘可能簡短和專注。很容易出錯,在錯誤處理程序中彈出錯誤並導致意外。

如果這不是您所需要的,請說明您的代碼中的內容不起作用。

1

只需捕獲錯誤並返回False

for n in stringy: 
    if n ==')': 
     try: 
      param_stack.pop() 
     except IndexError: 
      return False 
+0

我試過了,它似乎工作。然而,由於某種原因,我認爲,由於我的邏輯,'('附加到列表=/ – Liondancer

1

使用嘗試,除了趕上IndexError異常,然後返回False

try: 
    param_stack.pop() 
except IndexError: 
# catch your IndexError exception and do what you want 
    return False 
5

如果你只是想要一個if語句來檢查deque在pop()之前是空的,你可以使用

if n ==')': 
    if param_stack: 
     param_stack.pop() 
    else: 
     return false 
... 

if param_stack w如果它包含一些元素,則會將其隱式轉換爲布爾值,否則返回false。

2

需要注意的幾點:首先,您正在使用的deque的唯一方法是append()pop。所以使用普通的Python列表更自然。 deque並不比列表更有效率,除非你需要把事情放在一邊,或者把它放在「左端」。

其次,你已經知道如何測試一個空的雙層殼!你這樣做,在這裏:

if param_stack == []: 

現在這是一個有點古怪,因爲你是一個deque比較清單,但它的工作原理。隨着一點點更多的經驗,你會寫爲:

if len(param_stack) == 0: 

,並與更多的經驗是,你可以使用:

if not param_stack: 

(一個空的容器通常表現得像假的真-Y上下文)。

但是無論你如何寫它,而不是引進try/except塊,它更容易和更清晰做這樣的事情:

if n ==')': 
     if param_stack: # i.e., if it's not empty 
      param_stack.pop() 
     else: # it's empty 
      return False 

清除?

+0

非常清楚!謝謝你的例子! – Liondancer

1

至於其他人已經提到的,你並不真的需要一個隊列,一個簡單的計數器就足夠了:

def str_valid(txt): 
    ctr = 0 
    for n in txt: 
    if n == '(': 
     ctr = ctr + 1 
    if n == ')': 
     ctr = ctr - 1  
    if ctr < 0: 
     return False 
    return ctr == 0 

或更短:

def str_valid(txt): 
    ctr = 0 
    for n in txt: 
    ctr = ctr + (n == '(') - (n == ')') 
    if ctr < 0: 
     return False 
    return ctr == 0 

或者「哈克」的一行: )

def str_valid(txt): 
    return not reduce(lambda t, c: t if t < 0 else t + (c == '(') - (c == ')'), txt, 0)