对于小型数据集,您不会发现太大差异。但通常如果你想链接和迭代多个迭代器,那么你可以使用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 代码被使用了两次。这意味着首先添加list1 和list2,并创建一个临时列表,然后再次添加list3。如果任何列表非常大,这将非常低效。