2013-08-04 91 views
1

給定兩個列表,我想合併它們,以便第一個列表中的所有元素都是偶數索引(保留它們的順序),而第二個列表中的所有元素都是奇數索引的也保存他們的訂單)。示例如下:python合併兩個列表(偶數/奇數元素)

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

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

我可以使用for循環。但我想可能會有一種奇特的方式來做到這一點(使用一個不太知名的功能或類似的東西)。有沒有更好的解決方案來編寫for循環?

編輯:我在想列表解析,但到目前爲止沒有提出任何解決方案。

+0

你想做什麼的'X = [0,1,2,3,4,5,6]''但做ÿ = [20,21]',或者相反呢? (也就是說,如果一個列表比另一個列表長得多或者比另一個長得多) – torek

+0

假設更簡單的場景:len(x)== len(y)OR len(x)== len(y)+ 1,不用擔心。這將是一場比賽的一系列動作。 – ducin

+0

在這種情況下,請使用下面的'roundrobin'或簡化版。 – torek

回答

3

你可以簡單地做:

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

這需要的是插入將使用最後一個索引當overpassed的優勢。

一個例子:

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] 
+2

我喜歡這個,因爲它的簡單性 - 唯一需要解決的不是修改x。 (y):'/'res.insert(2 * i + 1,v)' – ducin

+3

@tkoomzaaskz'list.insert '是一個O(N)操作。 –

+0

@AshwiniChaudhary你的意思是複雜嗎?所以呢? (對不起,如果我不明白你的觀點) – ducin

7

以下是您可以使用的東西。 (使用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(...)刪除所有出現'',我們得到所需的答案。
+0

for len(x)= len(y)+1:'list(chain.from_iterable(zip(x,y )))+ [x [-1]]' – Muposat

4

試試這個:

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 

應該爲不均勻長列表工作。

5

使用roundrobinrecipeitertools

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] 
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)。

+0

是的,但是 - 正如我在問題中所寫的那樣 - 我可以使用for循環來做到這一點。我在想基於語法的東西(比如列表切片或列表解析)。無論如何,謝謝 – ducin

+0

這會錯過一些項目:'paired(y,x)'。 –

+0

@AshwiniChaudhary:這就是爲什麼當我問上面的問題時,如果一個列表比另一個列表長。 – torek

3

如果你有相同長度的列表,你可以使用這個:

result = [ item for tup in zip(x,y) for item in tup ] 
1

它可以與切片來完成。做countslice在終端:

>>> 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'] 
相關問題