依次迭代两个列表

问题描述 投票:0回答:4

我有两个数字列表

list1
list2
,我想用相同的指令迭代它们。像这样:

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

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

但这感觉是多余的。我知道我可以写

for item in list1 + list2:
,但它有运行时间的代价。

有没有一种方法可以在不浪费时间的情况下做到这一点?

python python-3.x list loops iteration
4个回答
53
投票

这可以通过

itertools.chain
来完成:

import itertools

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

for i in itertools.chain(l1, l2):
    print(i, end=" ")

将打印:

1 2 3 4 5 6 7 8 

根据文档,

chain
执行以下操作:

创建一个迭代器,从第一个可迭代对象返回元素,直到它耗尽,然后继续处理下一个可迭代对象,直到所有可迭代对象都耗尽。

如果您的列表中有列表,则可以使用

itertools.chain.from_iterable

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

这会产生相同的结果。

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

def custom_chain(*it):
    for iterab in it:
        yield from iterab

这需要 Python 3,对于 Python 2,只需

yield
使用循环将它们返回:

def custom_chain(*it):
    for iterab in it:
        for val in iterab:
            yield val

除了前面的之外,Python

3.5
及其扩展的解包泛化,还允许在列表文字中解包:

for i in [*l1, *l2]:
    print(i, end=" ")

虽然这比

l1 + l2
稍快,但它仍然构造一个列表,然后将其丢弃;仅将其作为最终解决方案。


16
投票

chain
有效,但如果您觉得导入模块只是为了调用一次单个函数有点过分,您可以内联复制其行为:

for seq in (list1, list2):
  for item in seq:
    print(item.amount)
    print(item.total_amount)

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


0
投票

多次执行后,最快的替代方案是第二个。

import itertools
from time import time

l1 = list(range(1000))
l2 = list(range(1000))

print('Alternative 1. Itertools')
t = time()
for j in range(10000):
    s = 0
    for i in itertools.chain(l1, l2):
        s += i
print(time() - t)

print('Alternative 2. Naive')
t = time()
for j in range(10000):
    s = 0
    for i in [*l1, *l2]:
        s += i
print(time() - t)

print('Alternative 3. Yield')
def chain(*ls):
    for l in ls:
        for k in l:
            yield k
t = time()
for j in range(10000):
    s = 0
    for i in chain(l1, l2):
        s += i
print(time() - t)

-2
投票

这个怎么样:

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

只有3行

© www.soinside.com 2019 - 2024. All rights reserved.