私はいくつかの述語を持っています、例えば:
is_divisible_by_13 = lambda i: i % 13 == 0
is_palindrome = lambda x: str(x) == str(x)[::-1]
次のようにそれらを論理的に結合したい:
filter(lambda x: is_divisible_by_13(x) and is_palindrome(x), range(1000,10000))
問題は次のとおりです。このような組み合わせは、次のような無意味なスタイルで記述できますか?
filter(is_divisible_by_13 and is_palindrome, range(1000,10000))
もちろん、ラムダ関数の真偽値はTrue
andand
とor
短絡演算子であるため、これは望ましい効果をもたらしません。私が思いついた最も近いものは、メソッドを実装して持つ単純P
な述語コンテナーであるクラスを定義し、述語を結合することでした。の定義は次のとおりです。__call__()
and_()
or_()
P
import copy
class P(object):
def __init__(self, predicate):
self.pred = predicate
def __call__(self, obj):
return self.pred(obj)
def __copy_pred(self):
return copy.copy(self.pred)
def and_(self, predicate):
pred = self.__copy_pred()
self.pred = lambda x: pred(x) and predicate(x)
return self
def or_(self, predicate):
pred = self.__copy_pred()
self.pred = lambda x: pred(x) or predicate(x)
return self
P
次のような述語の組み合わせである新しい述語を作成できるようになりました。
P(is_divisible_by_13).and_(is_palindrome)
これは上記のラムダ関数と同等です。これは私が望んでいるものに近づきますが、無意味でもありません (ポイントは、引数ではなく述語そのものになりました)。2番目の質問は次のとおりですP
。(ラムダ)関数を使用せずにクラスのようなクラスを使用するよりも、Pythonで述語を結合するためのより良いまたはより短い方法(おそらく括弧とドットなし)はありますか?