An elegant and fast way to consecutively iterate o

2020-02-20 07:12发布

I have three collection.deques and what I need to do is to iterate over each of them and perform the same action:

for obj in deque1:  
    some_action(obj)  

for obj in deque2:  
    some_action(obj)

for obj in deque3:  
    some_action(obj)

I'm looking for some function XXX which would ideally allow me to write:

for obj in XXX(deque1, deque2, deque3):  
    some_action(obj)

The important thing here is that XXX have to be efficient enough - without making copy or silently using range(), etc. I was expecting to find it in built-in functions, but I found nothing similar to it so far.

Is there such thing already in Python or I have to write a function for that by myself?

9条回答
Fickle 薄情
2楼-- · 2020-02-20 07:49

Use itertools.chain(deque1, deque2, deque3)

查看更多
乱世女痞
3楼-- · 2020-02-20 07:53

Depending on what order you want to process the items:

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)

I'd recommend doing this to avoid hard-coding the actual deques or number of deques:

deques = [deque1, deque2, deque3]
for item in itertools.chain(*deques):
    some_action(item)

To demonstrate the difference in order of the above methods:

>>> 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
>>>
查看更多
祖国的老花朵
4楼-- · 2020-02-20 07:53

The answer is in itertools

itertools.chain(*iterables)

Make an iterator that returns elements from the first iterable until it is exhausted, then proceeds to the next iterable, until all of the iterables are exhausted. Used for treating consecutive sequences as a single sequence. Equivalent to:

def chain(*iterables):
    # chain('ABC', 'DEF') --> A B C D E F
    for it in iterables:
        for element in it:
            yield element
查看更多
倾城 Initia
5楼-- · 2020-02-20 07:53

I would simply do this :

for obj in deque1 + deque2 + deque3:  
some_action(obj)  
查看更多
▲ chillily
6楼-- · 2020-02-20 07:55

It looks like you want itertools.chain:

"Make an iterator that returns elements from the first iterable until it is exhausted, then proceeds to the next iterable, until all of the iterables are exhausted. Used for treating consecutive sequences as a single sequence."

查看更多
Rolldiameter
7楼-- · 2020-02-20 07:56

Accepts a bunch of iterables, and yields the contents for each of them in sequence.

def XXX(*lists):
   for aList in lists:
      for item in aList:
         yield item



l1 = [1, 2, 3, 4]
l2 = ['a', 'b', 'c']
l3 = [1.0, 1.1, 1.2]

for item in XXX(l1, l2, l3):
   print item

1
2
3
4
a
b
c
1.0
1.1
1.2
查看更多
登录 后发表回答