我非常喜欢Python生成器。特别是,我发现它们是连接Rest端点的理想工具 - 我的客户端代码只需迭代与端点相连的生成器即可。然而,我发现Python的生成器在一个领域不如我所希望那样表达。通常,我需要过滤从端点获取的数据。在我的当前代码中,我将谓词函数传递给生成器,它将谓词应用于正在处理的数据,仅在谓词为True时产生数据。
我希望向生成器组合的方向发展 - 如 data_filter(datasource())。以下是一些演示代码,显示了我尝试过的内容。很明显,它为什么无法工作,我正在努力找到最富有表现力的方法来解决问题:
# Mock of Rest Endpoint: In actual code, generator is
# connected to a Rest endpoint which returns dictionary(from JSON).
def mock_datasource ():
mock_data = ["sanctuary", "movement", "liberty", "seminar",
"formula","short-circuit", "generate", "comedy"]
for d in mock_data:
yield d
# Mock of a filter: simplification, in reality I am filtering on some
# aspect of the data, like data['type'] == "external"
def data_filter (d):
if len(d) < 8:
yield d
# First Try:
# for w in data_filter(mock_datasource()):
# print(w)
# >> TypeError: object of type 'generator' has no len()
# Second Try
# for w in (data_filter(d) for d in mock_datasource()):
# print(w)
# I don't get words out,
# rather <generator object data_filter at 0x101106a40>
# Using a predicate to filter works, but is not the expressive
# composition I am after
for w in (d for d in mock_datasource() if len(d) < 8):
print(w)
filter()
函数有什么感觉? - Kevinlambda
来调用filter
,这样你就会得到一个笨重的表达式。当过滤函数已经存在时(例如str.isdigit
、None
用于测试真值等),filter
是很好的选择。 - Jean-François Fabrefilter
在字符串上非常有用,因为它可以避免使用str.join
。现在这种乐趣已经消失了 :) - Jean-François Fabre