为了账号安全,请及时绑定邮箱和手机立即绑定

Python:过滤可迭代类

Python:过滤可迭代类

呼唤远方 2022-12-06 15:29:13
是否有一个Iterable对象可以持有的钩子/dunder,以便内置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, Iterableclass 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在该对象上调用时应该如何表现?如果不是,关于过滤可迭代对象的最佳实践或标准是什么?
查看完整描述

1 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

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


为了不让您空手而归,这是 filtered_iter您提出的一个更简洁的版本,它动态地对给定类进行子类化,将其__iter__方法与filter.


def filter_iter(p, cls):

    class _(cls):

        def __iter__(self):

            yield from filter(p, super().__iter__())

    return _


查看完整回答
反对 回复 2022-12-06
  • 1 回答
  • 0 关注
  • 110 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信