wds*_*wds 3 python iterator functional-programming
我正在通过脚本流式传输一个非常大的集合,目前正在使用ifilter一个简单的调用来拒绝某些值,即:
ifilter(lambda x: x in accept_list, read_records(filename))
Run Code Online (Sandbox Code Playgroud)
这是一个谓词,但现在我发现我应该添加另一个,我可能希望将来添加其他谓词.直截了当的方式是嵌套一个ifilter电话:
ifilter(lambda x : x not in block_list,
ifilter(lambda x: x in accept_list, read_records(filename)))
Run Code Online (Sandbox Code Playgroud)
我想简单地将谓词作为未绑定的函数放在列表中并使用它们.虽然这些重复的ifilter调用似乎很难实现(并且可能不是最佳选择).也许我可以构造一个调用所有谓词的函数,但是如何尽可能简洁地(虽然仍然可读)编写它?
您可以编写以下函数:
def conjoin(*fns):
def conjoined(x):
for fn in fns:
if not fn(x): return False
return True
return conjoined
Run Code Online (Sandbox Code Playgroud)
然后你会这样称呼它:
ifilter(conjoined(lambda x: x not in block_list, lambda x: x in accept_list),
read_records(filename))
Run Code Online (Sandbox Code Playgroud)
你可以一起disjoin为or -ing函数实现一个类似的函数:
def disjoin(*fns):
def disjoined(x):
for fn in fns:
if fn(x): return True
return False
return disjoined
Run Code Online (Sandbox Code Playgroud)
可能有更好的方法来实现它们,但必须要小心.有人可能会尝试将每个函数应用于x和使用all或any,但这是不可取的,因为使用它们将需要评估参数的每个谓词.这里提出的解决方案是令人满意的短路.
另外,为了好玩,让我们实现一个invert功能
def invert(fn):
return lambda x: not fn(x)
Run Code Online (Sandbox Code Playgroud)
现在,我们有一套功能完备的函数操作函数,并且可以构造这些函数中的任何逻辑运算:)