aheadlead
V2EX  ›  问与答

Python 求问,如何把一个 list 中相邻两项构成一个 tuple 并得到一个 tuple 的 list

  •  
  •   aheadlead · Aug 24, 2014 · 7778 views
    This topic created in 4458 days ago, the information mentioned may be changed or developed.
    例
    in
    [1,2,3,4,5,6,7,8]
    out
    [(1,2),(3,4),(5,6),(7,8)]

    求优雅写法...

    谢谢
    15 replies  •  2014-08-26 10:35:56 +08:00
    binux
    binux
    Aug 24, 2014❤️4
    1
    zip(list[::2], list[1::2])
    raquelken
    raquelken
    Aug 24, 2014❤️1
    2
    a = [1,2,3,4,5,6,7,8]
    zip(a[0:-1:2], a[1:-1:2])
    aheadlead
    aheadlead
    OP
    Aug 24, 2014
    3
    @binux 感谢!
    初学python中.0.
    exoticknight
    exoticknight
    Aug 24, 2014
    4
    binux果然是python高手……
    wy315700
    wy315700
    Aug 24, 2014
    5
    学习了,顺便收藏
    imn1
    imn1
    Aug 24, 2014❤️1
    6
    这个解决方案很多,像zip、itertools等等
    我遇到这种问题常在数据分析中,通常都已经import了numpy、pandas,所以常用其中的方法来变形数列~
    magine
    magine
    Aug 24, 2014
    7
    虽然有点不礼貌,但是建议楼主先读一下《python基础教程》之类的书。
    当然如果没打算长期使用就当我没说。
    starsoi
    starsoi
    Aug 24, 2014❤️1
    8
    b=iter(a)
    [(x, b.next()) for x in b]
    速度比上面的zip快,尤其是当a很大的时候

    Python 2.7.3

    >>> timeit('zip(a[::2], a[1::2])', setup='a=[1,2,3,4,5,6,7,8]', number=10000)
    0.00456690788269043

    >>> timeit('[(x, b.next()) for x in b]', setup='a=[1,2,3,4,5,6,7,8];b=iter(a)', number=10000)
    0.0014100074768066406

    >>> timeit('zip(a[::2], a[1::2])', setup='a=range(100000)', number=10000)
    21.61440110206604

    >>> timeit('[(x, b.next()) for x in b]', setup='a=range(100000);b=iter(a)', number=10000)
    0.022505998611450195
    hit9
    hit9
    Aug 24, 2014
    9
    >>> lst = [1,2,3,4,5,6,7,8]
    >>> zip(*[iter(lst)]*2)
    [(1, 2), (3, 4), (5, 6), (7, 8)]
    hit9
    hit9
    Aug 24, 2014
    10
    starsoi
    starsoi
    Aug 24, 2014
    11
    @hit9 zip(*[iter(lst)]*2) 太慢了

    >>> timeit('zip(*[iter(a)]*2)', setup='a=range(100000);b=iter(a)', number=10000)
    18.37099289894104

    受你的启发,这样可读性更高,而且也超快:

    b=iter(a)
    zip(b,b)

    >>> timeit('zip(b,b)', setup='a=range(100000);b=iter(a)', number=10000) 0.022648096084594727
    hit9
    hit9
    Aug 25, 2014
    12
    @starsoi 非常赞。你知道慢在哪里了吗?
    hit9
    hit9
    Aug 25, 2014
    13
    两者的开销差貌似只有" 放到list中再unpack到args中"
    starsoi
    starsoi
    Aug 25, 2014
    14
    @hit9 我的timeit多算了10000次的iter()的开销。。。把iter放到setup里就一样了

    >>> timeit('zip(*[b]*2)', setup='a=range(100000);b=iter(a)', number=10000)
    0.022448062896728516
    hit9
    hit9
    Aug 26, 2014
    15
    @starsoi 是的。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1466 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 04:43 · PVG 12:43 · LAX 20:43 · JFK 23:43
    ♥ Do have faith in what you're doing.