2016-03-04 9 views
7

Как Переберите мои 2 списка, так что я могу использоватьСоздать новый список, взяв первый элемент из первого списка, а последний элемент из второго списка

a=[1,2,3,8,12] 
b=[2,6,4,5,6] 

получить

[1,6,2,5,3,8,6,12,2] 

ИЛИ использовать

d=[a,b,c,d] 
e=[w,x,y,z] 

получить

[a,z,b,y,c,x,d,w] 

(первый элемент из 1-го списка, последний элемент из 2-го списка)
(второй элемент из 1-го списка, второй к последнему элементу из 2-го списка)

+0

Какую часть вы испытываете трудности с? –

ответ

11
[value for pair in zip(a, b[::-1]) for value in pair] 
5

Вы можете заархивировать первый список с обратным вторым (с использованием itertools.izip_longest), затем соединить столбцы, используя itertools.chain:

>>> d=['a','b','c','d'] 
>>> e=['w','x','y','z'] 
>>> 
>>> from itertools import chain, zip_longest # in python 2 use izip_longest 
>>> 
>>> list(chain(*izip_longest(d, e[::-1]))) 
['a', 'z', 'b', 'y', 'c', 'x', 'd', 'w'] 

преимущества использования zip_longest() в том, что он принимает fillvalue аргумента, который будет передан для заполнения опущенных элементов, когда длина списков не равна.

Если вы уверены, что длина списков одинакова, вам лучше использовать встроенную функцию zip().

>>> d=['a','b'] 
>>> e=['w','x','y','z'] 
>>> list(chain(*izip_longest(d, e[::-1], fillvalue=''))) 
['a', 'z', 'b', 'y', '', 'x', '', 'w'] 

Более вещий способ предложенный Clements @ Джон:

list(chain.from_iterable(zip_longest(d, reversed(e)))) 
+0

Считается, что лучше использовать 'chain.from_iterable (iterable)' вместо 'chain (* iterable)' ... и если вы хотите избежать создания нового списка вместо 'e [:: - 1]' you может использовать 'reverseed (e)' so all in all: 'list (chain.from_iterable (zip_longest (d, reverseed (e)))) ' –

+0

Возможно, метод, который я использовал бы, это взять рецепт' roundrobin' itertools и предоставить ему 'd' и' reverse (e) 'as input - это 'll обрабатывать красиво изменяющиеся списки длин (не беспокоясь о заполняемых значениях) и масштабируется до произвольного числа итераций в качестве ввода –

+0

@JonClements Да, использование 'reverse()' является лучшей идеей, но я думаю, что использование 'roundrobin' (хотя это pythonic way) в этом случае является излишним. – Kasramvd

0

Ну, я сделал несколько тестов для python2:

import time 
from operator import itemgetter 
from itertools import chain, izip_longest 

a = [1, 2, 3, 8, 12] 
b = [2, 6, 4, 5, 6] 

print "Using value and zip" 
starttime = time.time() 
c = [value for pair in zip(a, b[::-1]) for value in pair] 
elapsed = time.time() - starttime 
print c 
print elapsed 

print "Using chain and izip" 
starttime = time.time() 
c = list(chain(*izip_longest(a, b[::-1]))) 
elapsed = time.time() - starttime 
print c 
print elapsed 

print "Using itemgetter" 
c = [] 
starttime = time.time() 
for i in xrange(0, len(a)): 
    c.append(itemgetter(i)(a)) 
    c.append(itemgetter(len(b)-i-1)(b)) 
elapsed = time.time() - starttime 
print c 
print elapsed 

выход:

Using value and zip 
[1, 6, 2, 5, 3, 4, 8, 6, 12, 2] 
1.59740447998e-05 
Using chain and izip 
[1, 6, 2, 5, 3, 4, 8, 6, 12, 2] 
3.2901763916e-05 
Using itemgetter 
[1, 6, 2, 5, 3, 4, 8, 6, 12, 2] 
1.4066696167e-05 

Иногда первый метод быстрее, а иногда и третий.

Таковы результаты для списков Длинна = 1000:

Using value and zip 
0.000767946243286 
Using chain and izip 
0.000431060791016 
Using itemgetter 
0.00203609466553 

Как Вы можете видеть, что второй метод становится лучше для более длинных списков.

0

Как об этом:

a=[1,2,3,8,12] 
b=[2,6,4,5,6] 
>>> a1 = list(map(lambda x: a1.extend([x,0]), a)) 
[None, None, None, None, None] 
>>> a1 
[1, 0, 2, 0, 3, 0, 8, 0, 12, 0] 
>>> b1 = list(map(lambda x: b1.extend([0,x]), b[::-1])) 
[None, None, None, None, None] 
>>> b1 
[0, 6, 0, 5, 0, 4, 0, 6, 0, 2] 
>>> c = [x+y for x,y in zip(a1,b1)] 
>>> c 
[1, 6, 2, 5, 3, 4, 8, 6, 12, 2] 

Если а и Ь с различными длинами, то:

>>> c = [x+y for x,y in izip_longest(a1,b1)] #you choose your fillvalue. 
Смежные вопросы