最好,有效的方法来获得序列项的结果元组满足和不满足条件

时间:2010-09-06 09:18:01

标签: python filter generator data-partitioning

(这是专业的最佳实践/模式兴趣,而非家庭工作要求)

  • INPUT :任何无序序列或生成器,函数 myfilter(item)如果满足过滤条件则返回True

  • 输出(filter_true,filter_false)序列的元组 原始类型包含 按照分区划分的元素 按原始顺序过滤。

如果不进行双重过滤,您会如何表达这一点,还是应该使用双重过滤?也许过滤器和循环/生成器/列表comprehencion与next可以回答?

我是否应该考虑保持类型或只是改变要求给出元组/发电机结果的元组,我不能轻易返回发电机输入发电机,或者我可以吗? (要求是自制的)

此时测试最佳候选人,提供两个流而不是元组

import itertools as it
from sympy.ntheory import isprime as myfilter

mylist = xrange(1000001,1010000,2)
left,right = it.tee((myfilter(x), x) for x in mylist)
filter_true = (x for p,x in left if p)
filter_false = (x for p,x in right if not p)

print 'Hundred primes and non-primes odd  numbers'
print  '\n'.join( " Prime %i, not prime %i" %
                  (next(filter_true),next(filter_false))
                  for i in range(100))

4 个答案:

答案 0 :(得分:5)

以下是一种方法,只为每个项目调用myfilter一次,如果mylist是生成器,也可以使用

import itertools as it
left,right = it.tee((myfilter(x), x) for x in mylist)
filter_true = (x for p,x in left if p)
filter_false = (x for p,x in right if not p)

答案 1 :(得分:2)

让我们假设你的问题不是内存而是cpu,myfilter很重,你不想迭代和过滤两次原始数据集。以下是一些单一传递提示:

简单而通用的版本(记忆力很强):

filter_true=[]
filter_false=[]
for item in  items:
    if myfilter(item):
        filter_true.append(item)
    else:
        filter_false.append(item)  

内存友好版本:(不适用于生成器(除非与列表(项目)一起使用))

while items:
    item=items.pop()
    if myfilter(item):
        filter_true.append(item)
    else:
        filter_false.append(item)  

生成器友好版本:

while True:
    try:
        item=next(items)
        if myfilter(item):
            filter_true.append(item)
        else:
            filter_false.append(item)  
    except StopIteration:
        break

答案 2 :(得分:0)

简单方法(但效率较低)是tee迭代并过滤它们:

import itertools
left, right = itertools.tee( mylist )
filter_true = (x for x in left if myfilter(x))
filter_false = (x for x in right if myfilter(x))

这比最佳解决方案效率低,因为将为每个元素重复调用myfilter。也就是说,如果您在left中测试了一个元素,则不必在right中重新测试它,因为您已经知道了答案。如果您需要此优化,则应该难以实现:查看tee的实现以获取线索。你需要为每个返回的iterable提供一个双端队列,你可以使用原始序列的元素来存储它,但是还没有被要求。

答案 3 :(得分:-1)

我认为你最好的选择是建造两个独立的发电机:

filter_true = (x for x in mylist if myfilter(x))
filter_false = (x for x in mylist if not myfilter(x))