在同一循环中迭代两个列表

时间:2016-01-03 13:59:25

标签: python list python-3.x for-loop time

如何在Python中迭代两个列表?我想要完全是

的结果
list1, list2, list3 = [0, 1], ['a', 'b'], [2, 3] # example data

for item in list1 + list2 + list3:
    print(item)

但我认为添加列表然后迭代它们并不高效。我使用for循环来遍历列表:

for list_ in (list1, list2, list3):
    for item in list_:
        print(item)

但是当我用timeit检查时,两者的执行时间非常相似。

是否可以加快速度?

5 个答案:

答案 0 :(得分:6)

对于小型数据集,您不会发现太多差异。但通常如果你想链接和迭代多个迭代,那么你可以使用itertools.chain,就像这样

>>> list1, list2, list3 = [0, 1], ['a', 'b'], [2, 3]
>>> from itertools import chain
>>> for item in chain(list1, list2, list3):
...     print(item)
0
1
a
b
2
3

这不会创建任何中间数据结构并逐个迭代每个迭代。 chain返回的值是迭代器。所以这也不会创建一个包含所有项目的容器,如果迭代次数非常大,那么它的内存效率非常高。

itertools.chain实际上与您的第二种方法相同。引用官方文档中的等效实现

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

如果我们查看为您显示的第一个程序生成的字节代码,请使用此

from dis import dis
list1, list2, list3 = [0, 1], ['a', 'b'], [2, 3]


def func():
    for item in list1 + list2 + list3:
        print(item)

dis(func)

就像是

  6           0 SETUP_LOOP              27 (to 30)
              3 LOAD_GLOBAL              0 (list1)
              6 LOAD_GLOBAL              1 (list2)
              9 BINARY_ADD          
             10 LOAD_GLOBAL              2 (list3)
             13 BINARY_ADD          
             14 GET_ITER            
        >>   15 FOR_ITER                11 (to 29)
             18 STORE_FAST               0 (item)

  7          21 LOAD_FAST                0 (item)
             24 PRINT_ITEM          
             25 PRINT_NEWLINE       
             26 JUMP_ABSOLUTE           15
        >>   29 POP_BLOCK           
        >>   30 LOAD_CONST               0 (None)
             33 RETURN_VALUE        

如您所见,BINARY_ADD代码使用了两次。这意味着首先添加list1list2,然后创建一个临时列表,并再次添加list3。如果任何列表非常大,这将是非常低效的。

答案 1 :(得分:1)

使用itertools.chain

for item in itertools.chain(list1, list2, list2):
    print(item)

答案 2 :(得分:1)

您可以使用queryDatabase.GroupBy(x => x.Filename).Where(x => x.Count() == 1).Select(x => x.FirstOrDefault()).ToList(); 模块中的chain方法将三个列表链接为单个列表:

itertools

OR:

from itertools import chain:

for item in chain(list1, list2, list3):
    print(item)

答案 3 :(得分:0)

如果你是一个更多的人,这里有一个测试案例,证明在迭代之前将列表添加到一起是没有效率的。

请注意,hugelists.py包含三个列表,每个列表包含10,000个随机的四位数字。

from hugelists import list_one, list_two, list_three
from itertools import chain
from datetime import datetime

def method_one():
    start_time = datetime.now()
    for item in list_one + list_two + list_three:
        pass
    stop_time = datetime.now()
    return stop_time - start_time

def method_two():
    start_time = datetime.now()
    for item in chain(list_one, list_two, list_three):
        pass
    stop_time = datetime.now()
    return stop_time - start_time

if __name__ == "__main__":
    print method_one()
    print method_two()

结果:

> python test.py
0:00:00.001720
0:00:00.001014
> python test.py
0:00:00.001865
0:00:00.000997
> python test.py
0:00:00.001603
0:00:00.000833

答案 4 :(得分:0)

您可以尝试内置zip()功能。

>>> for m, n, k in zip([1,2,3,4,5], list('abcde'), [2,11,25,102,53]):
        print(m, n, k)


1 a 2
2 b 11
3 c 25
4 d 102
5 e 53

请注意,您可以将其他迭代项放入其中。

for m, n, k in zip(range(1,6), 'abcde', [2,11,25,102,53]):
    print(m, n, k)


1 a 2
2 b 11
3 c 25
4 d 102
5 e 53