一个接一个地迭代两个列表

Dub*_*bon 12 python iteration loops list python-3.x

我有两个列表list1list2数字,我想用相同的指令迭代它们.像这样:

for item in list1:
  print(item.amount)
  print(item.total_amount)

for item in list2:
  print(item.amount)
  print(item.total_amount)
Run Code Online (Sandbox Code Playgroud)

但这感觉多余.我知道我可以写for item in list1 + list2:,但它有运行时间的代价.

没有宽松的时间,有没有办法做到这一点?

Jim*_*ard 26

这可以通过以下方式完成itertools.chain:

import itertools

l1 = [1, 2, 3, 4]
l2 = [5, 6, 7, 8]

for i in itertools.chain(l1, l2):
    print(i, end=" ")
Run Code Online (Sandbox Code Playgroud)

哪个会打印:

1 2 3 4 5 6 7 8 
Run Code Online (Sandbox Code Playgroud)

根据文档,chain执行以下操作:

创建一个迭代器,它返回第一个iterable中的元素,直到它耗尽,然后进入下一个iterable,直到所有的iterables都用完为止.

如果列表中有列表,itertools.chain.from_iterable则可用:

l = [l1, l2]
for i in itertools.chain.from_iterable(l):
    print(i, end=" ")
Run Code Online (Sandbox Code Playgroud)

这产生了相同的结果.

如果您不想为此导入模块,则为其编写函数非常简单:

def custom_chain(*it):
    for iterab in it:
        yield from iterab
Run Code Online (Sandbox Code Playgroud)

这需要Python 3,对于Python 2,只需yield使用循环:

def custom_chain(*it):
    for iterab in it:
        for val in iterab:
            yield val
Run Code Online (Sandbox Code Playgroud)

除了之前的Python 3.5,其扩展的解包通用化,还允许在列表文字中解压缩:

for i in [*l1, *l2]:
    print(i, end=" ")
Run Code Online (Sandbox Code Playgroud)

虽然这比l1 + l2它仍然构造一个然后被抛出的列表稍微快一些; 只能作为最终解决方案.


Kev*_*vin 10

chain 工作,但如果你觉得导入一个模块只是为了调用一个函数一次是矫枉过正的,你可以内联复制它的行为:

for seq in (list1, list2):
  for item in seq:
    print(item.amount)
    print(item.total_amount)
Run Code Online (Sandbox Code Playgroud)

创建 (list1, list2) 元组在列表长度方面是 O(1),因此与将列表连接在一起相比,它的性能应该更好。