Skip to main content
 首页 » 编程设计

python之如何将一个迭代器一分为二

2025年05月04日39java哥

如何在不迭代两次或使用额外内存存储所有数据的情况下将一个迭代器拆分为两个?

当您可以将所有内容都存储在内存中时的解决方案:

l = [{'a': i, 'b': i * 2} for i in range(10)] 
def a(iterator): 
    for item in iterator: 
        print(item) 
def b(iterator): 
   for item in iterator: 
        print(item) 
 
a([li['a'] for li in l]) 
b([li['b'] for li in l]) 

或者如果你可以迭代两次,

class SomeIterable(object): 
    def __iter__(self): 
        for i in range(10): 
            yield {'a': i, 'b': i * 2} 
 
 
def a(some_iterator): 
    for item in some_iterator: 
        print(item) 
 
 
def b(some_iterator): 
    for item in some_iterator: 
        print(item) 
 
 
s = SomeIterable() 
 
a((si['a'] for si in s)) 
b((si['b'] for si in s)) 

但是如果我只想迭代一次,我该怎么做呢?

请您参考如下方法:

从注释中的说明来看,a 和b 是您不能重写的外部库函数,但可以交错执行。在那种情况下,你想要的是可能的,但它几乎需要线程:

import multiprocessing.pool # for ThreadPool, not multiprocessing 
import Queue 
 
_endofinput = object() 
 
def _queueiter(queue): 
    while True: 
        item = queue.get() 
        if item is _endofinput: 
            break 
        yield item 
 
def parallel_execute(funcs, iterable, maxqueue): 
    '''Interleaves the execution of funcs[0](iterable), funcs[1](iterable), etc. 
 
    No function is allowed to lag more than maxqueue items behind another. 
    (This will require adjustment if a function might return before consuming 
    all input.) 
 
    Makes only one pass over iterable. 
 
    ''' 
 
    queues = [Queue.Queue(maxsize=maxqueue) for func in funcs] 
    queueiters = [_queueiter(queue) for queue in queues] 
    threadpool = multiprocessing.pool.ThreadPool(processes=len(funcs)) 
 
    results = threadpool.map_async(lambda (f, x): f(x), zip(funcs, queueiters)) 
 
    for item in iterable: 
        for queue in queues: 
            queue.put(item) 
 
    for queue in queues: 
        queue.put(_endofinput) 
 
    threadpool.close() 
    return results.get()