2016-08-25 43 views
0

我有一個複雜的系統後端,但我試圖做一個簡單的例子,所以你知道我在說什麼。是否有Python方法來檢查列表元素,並停止在列表的末尾(沒有錯誤)?

基本上我有一個ID列表,一個用戶(通過一個GUI)將循環通過這個列表生成ID。

在某些時候,他們想要通過並修復所有他們搞砸或跳過的東西(這些都會有相同的ID);這是我遇到問題的地方。

我已經寫了一些確實如此(檢查列表中的壞ID),但問題是一旦它到達列表的末尾,它會引發索引錯誤。我想完全退出while循環和功能,而不是

def nextID(): 
    ''' 
     increment counter until we find a junk ID 
    ''' 
    global tindx 

    skips = 0 
    while IDs[tindx] != 'junk_id' and tindx != len(IDs): 
     print 'This ID is good: %s' %IDs[tindx] 
     skips+=1 
     tindx+=1  
    print 'Skipped %i IDs' %(skips), 'tindx is now',tindx 

這種設計(又一個巨大的簡化)以下列方式使用

tindx = 0 

IDs = ['abc','bcd','cde','junk_id','junk_id','def','efg','junk_id','fgh','ghi'] 

# This is all hadled with in an interactive GUI 
# User wants next ID 
nextID() 
# User changes ID 
IDs[tindx] = 'good_id!' 
# User wants next ID 
nextID() 
# User changes ID 
IDs[tindx] = 'another_good_id' 
# etc .... 

我知道,如果我切換while循環條件的順序,它將避免自動IndexError,但用戶不知道他們已經到達列表的末尾,並嘗試更改ID(獲取相同的錯誤)。

我想告訴用戶他們已經完成運行save_IDs()函數,並退出程序。重新設計的軟件這方面,有沒有比添加以下if條件更好的辦法

while ... 

    if tindx == len(IDs): 
     print 'you\'re done' 
     save_IDs() 
     return None 

回答

1

正如你所提到的,你需要切換參數的同時:

while tindx != len(IDs) and IDs[tindx] != 'junk_id': 
    ... 

否則將首先嚐試訪問ID [tindx],然後檢查它是否無效。

對於這個問題,你可以有nextID返回新索引或無當它到達終點:

def nextID(last_offset): 
    offset = last_offset 

    while offset < len(IDs) and IDs[offset] != 'junk_id' 
     offset += 1 

    if offset >= len(IDs): 
     return None 

    if offset > last_offset: 
     print("Skipped %d IDs" % (offset - last_offset)) 

    return offset 

然後使用它:

current_offset = 0 
while doing things: 
    current_offset = nextID(current_offset) 
    if current_offset == None: 
     # All done. 
     break 

    print("New offset: %d" % (offset)) 

    if user changes id: 
     IDs[current_offset] = 'good_id!' 
    else: 
     # If the user didn't change the ID for whatever reason, 
     # you'll need to manually increment current_offset. 
     current_offset += 1 

print("All done, saving..") 
saveIDs() 

如果您在回調中在裏面一個GUI,那麼你可能有更多這樣的:

def userChangedID(new_value): 
    global current_offset 

    IDs[current_offset] = new_value 
    current_offset = nextID(current_offset) 

    if current_offset == None: 
     finish() 

def userSkippedID(): 
    global current_offset 

    current_offset = nextID(current_offset + 1) 

    if current_offset == None: 
     finish() 

def finish(): 
    global finished 

    finished = True 
    print("All done, saving...") 
    saveIDs() 

理想的方法應該儘可能少的副作用因爲它需要做它應該做的事情。

在原始代碼中,nextID()不僅是'查找下一個ID',而且還改變了整個過程的狀態。

從開發人員的角度來看,這很容易讓人產生誤解,他可能只是期待nextID()來查找並返回下一個ID。

+0

我很欣賞你關於我對nextID的定義的觀點。由於在很大程度上自我教導,這是我遇到的一個常見問題。 你給出的例子讀得好多了,並且認爲我將重構我用來模擬這個的函數。這將是一個有點工作,但我可能會後來感謝自己。感謝您爲我展示這一點。 – FriskyGrub

相關問題