我寫了一個簡單的腳本來解決一個「邏輯謎題」,這是一種來自學校的謎題類型,您可以在其中獲得許多規則,然後必須能夠找到問題的解決方案,例如「有五個音樂家名爲A,B ,C,D和E在一場音樂會中演奏,每一個都依次演奏......如果A在B之前,而D不是最後......誰在什麼時候演奏?等是否有Python語言用於評估短路的函數/表達式列表?
評估可能的解決方案,我寫的每一個「規則」作爲一個獨立的功能,如果可能的解決方案(簡單地表示爲一個字符串列表)是有效的,其將評估,例如
#Fifth slot must be B or D
def rule1(solution):
return solution[4] == 'B' or solution[4] == 'D'
#There must be at least two spots between A and B
def rule2(solution):
returns abs(solution.index('A') - solution.index('B')) >= 2
#etc...
我對尋找Pythonic方法感興趣,以測試一個可能的解決方案是否通過了所有這些規則,並能夠在第一個失敗後停止評估規則。
起初,我寫了簡單的方式就是:
def is_valid(solution):
return rule1(solution) and rule2(solution) and rule3(solution) and ...
但這似乎相當難看。我想也許我能做出這樣讀的東西,如一個列表理解多一點優雅......
def is_valid(solution)
rules = [rule1, rule2, rule3, rule4, ... ]
return all([r(solution) for f in rules])
...但後來我意識到,自從all()
功能之前生成的列表中理解評估,即這具有根本不會短路的副作用 - 即使第一個返回False
,也將評估每個規則。
所以我的問題是:是否有一個更Python /功能性的方式才能夠評估True
/False
表情列表,以及短路,而不需要寫出來的return f1(s) and f2(s) and f3(s) ...
一個長長的清單?
所以這裏的基本區別是省略了'return all([r(solution)for r in rules])'中的括號,因此在'all()'被評估之前不會創建所有結果的列表? – 2010-08-04 13:16:10
是的。在這兩種情況下,「all」的參數在傳遞之前進行評估,但評估列表理解會在內存中創建整個列表,而評估生成器表達式會創建一個生成器對象,該對象根據需要加載元素。 – katrielalex 2010-08-04 13:19:21
完美,這使得很多感 - 感謝 – 2010-08-04 13:23:47