Bir "mantık bulmacasını" çözmek için basit bir betik yazdım, okuldan bir takım kuralların verildiği bir bulmaca türü var ve o zaman problemler için çözüm bulmalıyım. "A, B adlı beş müzisyen var. Bir konserde oynayan C, D ve E, her biri birbiri ardına oynar ... Eğer A, B'den önce gelirse ve D son değil ... Kimin ne zaman oynar? vbKısa devre ile fonksiyonların/ifadelerin bir listesini değerlendirmek için bir Python deyim var mı?
Ben örnek
#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...
Ben, (dizeleri bir liste olarak basitçe gösterilen) bir olası çözüm geçerli olup olmadığını değerlendirmek olurdu ayrı bir fonksiyonu olarak her bir "kural" yazdınız olası çözümleri değerlendirmek Olası bir çözümün tüm bu kuralları geçip geçmediğini test etmek için Pythonic yolunu bulmakla ilgileniyorum, ilk başarısızlıktan sonra kuralları değerlendirmeyi bırakma becerisi.
İlk başta ben mümkün olan en basit şeyi yazdım:
def is_valid(solution):
return rule1(solution) and rule2(solution) and rule3(solution) and ...
Ama bu oldukça çirkin görünüyordu. O, ben ... Bunun bir liste anlayışı gibi bir şey ile biraz daha zarif okumak yapabiliriz belki
def is_valid(solution)
rules = [rule1, rule2, rule3, rule4, ... ]
return all([r(solution) for f in rules])
düşündü ... ama sonra liste anlama all()
işlevi önce oluşturulan beri değerlendirilir fark Bu, hiç de kısa devre olmadığının yan etkisine sahiptir - ilk kurallar False
ilk versiyse bile her kural değerlendirilecektir.
Yani benim soru: kısa devre edildiği, True
/False
ifadelerin listesini değerlendirmek edebilmek için daha Pythonic/işlevsel yolu return f1(s) and f2(s) and f3(s) ...
uzun bir listesini yazmaya gerek kalmadan, var mı?
Buradaki temel fark, köşeli parantezleri içermezken, tümü ([r (çözüm) için kurallar için])), böylece tüm() 'nin değerlendirilmesinden önce tüm sonuçların bir listesini oluşturmaz. –
Evet. Her iki durumda da "all" argümanı geçilmeden önce değerlendirilir, ancak liste kavramasının değerlendirilmesi tüm listeyi hafızada oluştururken, bir generatör ifadesini değerlendirmek elemanları talep üzerine yükleyen bir jeneratör nesnesi oluşturur. – katrielalex
Mükemmel, bu çok mantıklı - teşekkürler –