在python中混合两个列表的最糟糕的方法
让我们有两张清单在python中混合两个列表的最糟糕的方法,python,list,Python,List,让我们有两张清单 l1 = [1, 2, 3] l2 = [a, b, c, d, e, f, g...] 结果: list = [1, a, 2, b, 3, c, d, e, f, g...] 无法使用zip(),因为它将结果缩短为最小的列表。我还需要一个列表,而不是iterable >>> l1 = [1,2,3] >>> l2 = ['a','b','c','d','e','f','g'] >>> [i for i in ite
l1 = [1, 2, 3]
l2 = [a, b, c, d, e, f, g...]
结果:
list = [1, a, 2, b, 3, c, d, e, f, g...]
无法使用zip()
,因为它将结果缩短为最小的列表。我还需要一个列表
,而不是iterable
>>> l1 = [1,2,3]
>>> l2 = ['a','b','c','d','e','f','g']
>>> [i for i in itertools.chain(*itertools.izip_longest(l1,l2)) if i is not None]
[1, 'a', 2, 'b', 3, 'c', 'd', 'e', 'f', 'g']
要允许列表中包含None
值,可以使用以下修改:
>>> from itertools import chain, izip_longest
>>> l1 = [1, None, 2, 3]
>>> l2 = ['a','b','c','d','e','f','g']
>>> sentinel = object()
>>> [i
for i in chain(*izip_longest(l1, l2, fillvalue=sentinel))
if i is not sentinel]
[1, 'a', None, 'b', 2, 'c', 3, 'd', 'e', 'f', 'g']
另一种可能性
[y for x in izip_longest(l1, l2) for y in x if y is not None]
(当然,在从itertools导入izip_longest后)如果需要在单个列表中而不是元组列表中输出,请尝试以下方法
Out=[]
[(Out.extend(i) for i in (itertools.izip_longest(l1,l2))]
Out=filter(None, Out)
我并不认为这是最好的方法,但我只是想指出,使用zip是可能的:
b = zip(l1, l2)
a = []
[a.extend(i) for i in b]
a.extend(max([l1, l2], key=len)[len(b):])
>>> a
[1, 'a', 2, 'b', 3, 'c', 'd', 'e', 'f', 'g']
做到这一点的最简单方法是使用以下给出的循环往复:
可以这样使用:
>>> l1 = [1,2,3]
>>> l2 = ["a", "b", "c", "d", "e", "f", "g"]
>>> list(roundrobin(l1, l2))
[1, 'a', 2, 'b', 3, 'c', 'd', 'e', 'f', 'g']
请注意,2.x需要一个稍有不同版本的roundrobin
,在中提供
这也避免了zip_longest()
方法存在的问题,即列表可以包含None
,而无需将其剥离出来。最快、最优雅或最具pythonic?无需使用双括号itertools.chain(…)
可以是itertools.chain(…)
。哦,您可能希望将整个内容封装在列表(…)
中。这是首选的,即使不是最具描述性的。:)您指的是什么“不必要的依赖关系”?到目前为止,由任何其他解决方案表示的唯一其他依赖项是itertools
,它是python标准库的一部分。是的,但它仍然必须由解释器加载。我并不是说其他解决方案不好,它们在大多数情况下可能更好,但我只是发布了另一种方法。除了它在Python 3中无法正常工作外,因为那里没有定义len(zip)
。对副作用使用列表理解也是个坏主意。请改用itertools.chain()
。考虑到您必须定义一个全新的函数才能使其工作,我不知道我是否会将其称为最简单的方法。@asmeur因为它是一个给定的配方,所以包含它并不困难。它还有我在底部提到的好处-如果列表包含None
则zip\u longest()
方法无法按预期工作。从使用角度来看,该功能清晰简单。@Lattyware我为None
问题添加了一个简单的修复程序,用于izip_最长的
解决方案。我现在看到的这个方法的唯一优点是速度优势,即不必迭代并丢弃大量哨兵。@jamylak我认为这个解决方案更清晰,可读性更强,这本身是有价值的。这假定b
比a
长,尽管这可以通过更多的代码来修复。
>>> a = [1, 2, 3]
>>> b = list("abcdefg")
>>> [x for e in zip(a, b) for x in e] + b[len(a):]
[1, 'a', 2, 'b', 3, 'c', 'd', 'e', 'f', 'g']
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while pending:
try:
for next in nexts:
yield next()
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
>>> l1 = [1,2,3]
>>> l2 = ["a", "b", "c", "d", "e", "f", "g"]
>>> list(roundrobin(l1, l2))
[1, 'a', 2, 'b', 3, 'c', 'd', 'e', 'f', 'g']
>>> a = [1, 2, 3]
>>> b = list("abcdefg")
>>> [x for e in zip(a, b) for x in e] + b[len(a):]
[1, 'a', 2, 'b', 3, 'c', 'd', 'e', 'f', 'g']