【问题标题】:Create new list by taking first item from first list, and last item from second list通过从第一个列表中获取第一项,从第二个列表中获取最后一项来创建新列表
【发布时间】:2016-03-04 13:38:43
【问题描述】:

如何遍历我的 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]

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

【问题讨论】:

  • 你在哪个部分有困难?

标签: python list python-3.x


【解决方案1】:
[value for pair in zip(a, b[::-1]) for value in pair]

【讨论】:

    【解决方案2】:

    您可以将第一个列表与第二个列表相反(使用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 建议的更多 Pythonic 方式:

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

    【讨论】:

    • 使用chain.from_iterable(iterable)而不是chain(*iterable)被认为是更好的形式...如果你想避免创建一个新列表,而不是e[::-1]你可以使用reversed(e)所以全部全部:list(chain.from_iterable(zip_longest(d, reversed(e))))
    • 也许我使用的方法是采用 roundrobin itertools 配方,并提供 dreversed(e) 作为输入 - 这将很好地处理不同长度的列表(不用担心关于填充值)并将缩放到任意数量的可迭代作为输入
    • @JonClements 是的,使用reverse() 是一个更好的主意,但我认为在这种情况下使用roundrobin(虽然是pythonic 方式)是矫枉过正。
    【解决方案3】:

    嗯,我对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
    

    如您所见,第二种方法更适合较长的列表。

    【讨论】:

      【解决方案4】:

      这个怎么样:

      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.
      

      【讨论】:

        猜你喜欢
        • 2015-01-18
        • 2022-10-03
        • 1970-01-01
        • 1970-01-01
        • 2017-03-27
        • 2021-09-03
        • 1970-01-01
        • 2017-11-05
        • 1970-01-01
        相关资源
        最近更新 更多