4

Given two lists, I want to merge them so that all elements from the first list are even-indexed (preserving their order) and all elements from second list are odd-indexed (also preserving their order). Example below:

x = [0,1,2]
y = [3,4]

result = [0,3,1,4,2]

I can do it using for loop. But I guess there could be a fancy pythonic way of doing this (using a less-known function or something like that). Is there any better solution that writing a for-loop?

edit: I was thinking about list comprehensions, but didn't come up with any solution so far.

4

7 回答 7

8

这是你可以使用的东西。(list(izip_longest(...))用于 Py2x)

>>> from itertools import chain
>>> from itertools import zip_longest
>>> list(filter(lambda x: x != '', chain.from_iterable(zip_longest(x, y, fillvalue = ''))))
[0, 3, 1, 4, 2]

这适用于任意长度的列表,如下所示 -

>>> x = [0, 1, 2, 3, 4]
>>> y = [5, 6]
>>> list(filter(lambda x: x != '', chain.from_iterable(zip_longest(x, y, fillvalue = ''))))
[0, 5, 1, 6, 2, 3, 4]

解释它的工作-

  1. zip_longest(...)使用填充值压缩列表并为长度不等的迭代填充给定的填充值。因此,对于您的原始示例,它的评估结果类似于[(0, 3), (1, 4), (2, '')]
  2. 我们需要展平结果,因为这个方法给了我们一个元组列表。为此,我们使用chain.from_iterable(...)给我们类似的东西[0, 3, 1, 4, 2, '']
  3. 我们现在使用filter(...)删除所有出现的'',我们得到所需的答案。
于 2013-08-04T10:15:51.993 回答
6

你可以简单地做:

for i,v in enumerate(y):
    x.insert(2*i+1,v)

这利用了 insert 在被超越时将使用最后一个索引的优势。

一个例子:

x = [0,1,2,3,4,5]
y = [100, 11,22,33,44,55,66,77]
print x
# [0, 100, 1, 11, 2, 22, 3, 33, 4, 44, 5, 55, 66, 77]
于 2013-08-04T10:27:25.497 回答
6

使用来自itertools的roundrobin 配方

from itertools import cycle, islice
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))
>>> list(roundrobin(x,y))
[0, 3, 1, 4, 2]
于 2013-08-04T10:18:32.480 回答
5

尝试这个:

x = [0,1,2,10,11]
y = [3,4]

n =  2*max([len(x),len(y)])
res = n *[None]
res[:2*len(x):2] = x
res[1:2*len(y):2] = y
res = [x for x in res if x!=None]
print res

它应该适用于不均匀的长列表。

于 2013-08-04T10:16:46.597 回答
4

If you have same length lists, you can use this:

result = [ item for tup in zip(x,y) for item in tup ]
于 2013-11-24T13:34:47.970 回答
2

这很简单,尽管不如以下灵活roundrobin

def paired(it1, it2):
    it2 = iter(it2)
    for item in it1:
        yield item
        yield next(it2)

在 2.7.5 中测试:

>>> x = [0, 1, 2]
>>> y = [3, 4]
>>> print list(paired(x, y))
[0, 3, 1, 4, 2]

请注意,一旦列表y用完,它就会停止(因为next(it2)引发了 StopIteration)。

于 2013-08-04T10:27:43.487 回答
2

它可以通过切片来完成。 在终端中执行count并:slice

>>> list1=['Apple','Mango','Orange']
>>> list2=['One','Two','Three']
>>> list = [None]*(len(list1)+len(list2))
>>> list[::2] = list1
>>> list[1::2] = list2
>>> list

输出:

 ['Apple', 'One', 'Mango', 'Two', 'Orange', 'Three']
于 2015-03-03T09:41:33.227 回答