Python:过滤可迭代的类

胸腺

是否有一个Iterable对象可以容纳的钩子/钩,以便可以将内置filter函数扩展到Iterable类(而不仅仅是实例)?

当然,可以编写一个自定义filter_iter函数,例如:

def filter_iter(filt_func: callable, collection_cls: type):
    name = 'Filtered' + collection_cls.__name__  # would this automatic scheme lead to namespace conflicts?
    wrapped_cls = type(name, (collection_cls,), {'_filt_func': staticmethod(filt_func)})
    def __iter__(self):
        yield from filter(self._filt_func, super(wrapped_cls, self).__iter__())
    wrapped_cls.__iter__ = __iter__
    return wrapped_cls

这将具有预期的效果。例如,

from collections import Collection, Iterable
class Chunker(Iterable):
    def __init__(self, source: Iterable, chk_size: int=2):
        self._source = source
        self._chk_size = chk_size
    def __iter__(self):
        yield from zip(*([iter(self._source)] * self._chk_size))


chunker = Chunker(range(12), 2)
assert list(chunker) == [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 11)]
FilteredChunker = filter_iter(lambda x: sum(x) % 3 == 0, Chunker)
filtered_chunker = FilteredChunker(range(12))
assert list(filtered_chunker) == [(4, 5), (10, 11)]

但是,就像有一个__iter__确定如何迭代对象钩子一样(例如,list在对象上调用时应如何表现),是否有一种__filter__钩子确定filter在对象上调用时应如何表现?

如果不是,围绕可迭代项的最佳实践或标准是什么?

切普纳

list(和__iter__例如)不同,没有这样的钩子filter后者只是迭代器协议的应用,而不是其本身的单独协议。

为了不让您空手,这里是filtered_iter您所建议的更为简洁的版本,该版本动态地给定类子类化,并使用组成其__iter__方法filter

def filter_iter(p, cls):
    class _(cls):
        def __iter__(self):
            yield from filter(p, super().__iter__())
    return _

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章