代码之家  ›  专栏  ›  技术社区  ›  Tony Veijalainen

得到满足和不满足条件的序列项的结果元组的最佳、有效的方法

  •  3
  • Tony Veijalainen  · 技术社区  · 15 年前

    • 输入 项目 ,函数 如果满足筛选条件,则返回True

    • : 序列元组 元素按 按原始顺序过滤。

    如果不进行双重过滤,您将如何表达这一点,或者我应该使用双重过滤?也许过滤和循环/生成器/列表 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 回复  |  直到 8 年前
        1
  •  5
  •   John La Rooy    15 年前

    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)
    
        2
  •  2
  •   dugres    15 年前

    假设你的问题不是内存而是cpu,myfilter很重,你不想迭代和过滤原始数据集两次。这里有一些 思想:

    简单而多功能的版本(Memoryvour):

    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
    
        3
  •  0
  •   Katriel    15 年前

    简单的方法(但效率较低)是 tee iterable和filter两者:

    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 因为你已经知道答案了。如果您需要这种优化,那么实现起来应该不难:看看 寻找线索。对于每个返回的iterable,您都需要一个deque,其中包含了原始序列中的元素,这些元素应该放在iterable中,但还没有被请求。

        4
  •  -1
  •   Johannes Charra    15 年前

    我认为最好的办法是建造两个独立的发电机:

    filter_true = (x for x in mylist if myfilter(x))
    filter_false = (x for x in mylist if not myfilter(x))
    
    推荐文章