从第一个列表中取第一个项目,从第二个列表中取最后一个项目来创建新列表

7
如何循环遍历我的两个列表以便使用它们?
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]

(第一个列表的第一个元素,第二个列表的最后一个元素)
(第一个列表的第二个元素,第二个列表的倒数第二个元素)

你在哪个部分遇到了困难? - Peter Wood
4个回答

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

5
你可以使用reverse第二个列表(使用 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']

Jon Clements建议的更加符合Python风格的方法:

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

最好使用chain.from_iterable(iterable)而不是chain(*iterable),以此保持良好的代码风格。如果您想避免创建新的列表,可以使用reversed(e)代替e[::-1],因此综合起来,建议使用list(chain.from_iterable(zip_longest(d, reversed(e)))) - Jon Clements
也许我会使用roundrobinitertools配方的方法,并将其提供给dreversed(e)作为输入 - 这将很好地处理长度不同的列表(无需担心填充值),并且可以扩展到任意数量的可迭代输入。 - Jon Clements
@JonClements 是的,使用 reverse() 更好,但我认为在这种情况下使用 roundrobin(虽然是 Pythonic 的方式)有些过度了。 - Mazdak

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]

如果a和b长度不同,则:
>>> c = [x+y for x,y in izip_longest(a1,b1)] #you choose your fillvalue.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接