以交替方式结合两个列表的Pythonic方法是什么?
我有两个列表,第一个列表的元素比第二个多一个。我想知道用最“Pythonic”的方式创建一个新列表,这个新列表的偶数索引位置的值来自第一个列表,而奇数索引位置的值来自第二个列表。
# example inputs
list1 = ['f', 'o', 'o']
list2 = ['hello', 'world']
# desired output
['f', 'hello', 'o', 'world', 'o']
这个方法可以实现,但看起来不太好:
list3 = []
while True:
try:
list3.append(list1.pop(0))
list3.append(list2.pop(0))
except IndexError:
break
还有什么其他方法可以做到这一点?最“Pythonic”的方式是什么?
如果你需要处理长度不匹配的列表(比如第二个列表更长,或者第一个列表比第二个多出多个元素),这里的一些解决方案可以用,而其他的可能需要调整。想要更具体的答案,可以查看 如何交错两个不同长度的列表?,以便把多余的元素放在最后,或者 如何优雅地交错两个不等长的列表?,尝试均匀地插入元素,或者 在Python列表中每隔n个元素插入一个元素,适用于需要在每个“添加”的元素前放置特定数量元素的情况。
相关问题:
26 个回答
55
import itertools
print(
[x for x in itertools.chain.from_iterable(itertools.zip_longest(list1, list2)) if x]
)
我觉得这是最符合Python风格的做法。
56
在这个itertools 文档里,有一个相关的例子(注意:这是针对Python 3的):
from itertools import cycle, islice
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
num_active = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while num_active:
try:
for next in nexts:
yield next()
except StopIteration:
# Remove the iterator we just exhausted from the cycle.
num_active -= 1
nexts = cycle(islice(nexts, num_active))
171
这里有一种通过切片来实现的方法:
>>> list1 = ['f', 'o', 'o']
>>> list2 = ['hello', 'world']
>>> result = [None]*(len(list1)+len(list2))
>>> result[::2] = list1
>>> result[1::2] = list2
>>> result
['f', 'hello', 'o', 'world', 'o']