在Python中连续迭代两个或更多容器的优雅而快速的方法?

izh*_*hak 25 python iterator

我有三个collection.deques,我需要做的是迭代它们并执行相同的操作:

for obj in deque1:  
    some_action(obj)  

for obj in deque2:  
    some_action(obj)

for obj in deque3:  
    some_action(obj)
Run Code Online (Sandbox Code Playgroud)

我正在寻找一些功能XXX,理想情况下我可以写:

for obj in XXX(deque1, deque2, deque3):  
    some_action(obj)
Run Code Online (Sandbox Code Playgroud)

这里重要的是XXX必须足够高效 - 没有复制或静默使用range()等.我期望在内置函数中找到它,但到目前为止我没有发现任何类似的东西.

Python中是否已有这样的东西,或者我必须自己编写一个函数?

Fog*_*ird 35

根据您要处理项目的顺序:

import itertools

for items in itertools.izip(deque1, deque2, deque3):
    for item in items:
        some_action(item)

for item in itertools.chain(deque1, deque2, deque3):
    some_action(item)
Run Code Online (Sandbox Code Playgroud)

我建议这样做是为了避免硬编码实际的deques或deques数量:

deques = [deque1, deque2, deque3]
for item in itertools.chain(*deques):
    some_action(item)
Run Code Online (Sandbox Code Playgroud)

为了证明上述方法的顺序差异:

>>> a = range(5)
>>> b = range(5)
>>> c = range(5)
>>> d = [a, b, c]
>>>
>>> for items in itertools.izip(*d):
...     for item in items:
...         print item,
...
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4
>>>
>>> for item in itertools.chain(*d):
...     print item,
...
0 1 2 3 4 0 1 2 3 4 0 1 2 3 4
>>>
Run Code Online (Sandbox Code Playgroud)


Dra*_*sha 14

答案是在itertools中

itertools.chain(*iterables)
Run Code Online (Sandbox Code Playgroud)

创建一个迭代器,它返回第一个iterable中的元素,直到它耗尽,然后进入下一个iterable,直到所有的iterables都用完为止.用于将连续序列作为单个序列处理.相当于:

def chain(*iterables):
    # chain('ABC', 'DEF') --> A B C D E F
    for it in iterables:
        for element in it:
            yield element
Run Code Online (Sandbox Code Playgroud)

  • `itertools`不是'iterutils` (3认同)

Joh*_*hin 6

叫我疯了,但为什么使用itertools被认为是必要的?有什么不对:

def perform_func_on_each_object_in_each_of_multiple_containers(func, containers):
    for container in containers:
        for obj in container:
            func(obj)

perform_func_on_each_object_in_each_of_multiple_containers(some_action, (deque1, deque2, deque3)
Run Code Online (Sandbox Code Playgroud)

更疯狂:你可能会使用一次.为什么不这样做:

for d in (deque1, deque2, deque3):
    for obj in d:
        some_action(obj)
Run Code Online (Sandbox Code Playgroud)

无需查看长名称函数的代码/文档或必须查找itertools.something()的文档,显而易见的是显而易见的


Mic*_*ber 5

使用 itertools.chain(deque1, deque2, deque3)