V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
aheadlead
V2EX  ›  问与答

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

  •  
  •   aheadlead · 2014-08-24 13:10:17 +08:00 · 6791 次点击
    这是一个创建于 3751 天前的主题,其中的信息可能已经有所发展或是发生改变。

    in
    [1,2,3,4,5,6,7,8]
    out
    [(1,2),(3,4),(5,6),(7,8)]

    求优雅写法...

    谢谢
    15 条回复    2014-08-26 10:35:56 +08:00
    binux
        1
    binux  
       2014-08-24 13:13:33 +08:00   ❤️ 4
    zip(list[::2], list[1::2])
    raquelken
        2
    raquelken  
       2014-08-24 13:15:05 +08:00   ❤️ 1
    a = [1,2,3,4,5,6,7,8]
    zip(a[0:-1:2], a[1:-1:2])
    aheadlead
        3
    aheadlead  
    OP
       2014-08-24 13:15:57 +08:00
    @binux 感谢!
    初学python中.0.
    exoticknight
        4
    exoticknight  
       2014-08-24 13:51:39 +08:00
    binux果然是python高手……
    wy315700
        5
    wy315700  
       2014-08-24 15:34:42 +08:00
    学习了,顺便收藏
    imn1
        6
    imn1  
       2014-08-24 19:09:06 +08:00   ❤️ 1
    这个解决方案很多,像zip、itertools等等
    我遇到这种问题常在数据分析中,通常都已经import了numpy、pandas,所以常用其中的方法来变形数列~
    magine
        7
    magine  
       2014-08-24 19:12:39 +08:00
    虽然有点不礼貌,但是建议楼主先读一下《python基础教程》之类的书。
    当然如果没打算长期使用就当我没说。
    starsoi
        8
    starsoi  
       2014-08-24 19:48:12 +08:00   ❤️ 1
    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
        9
    hit9  
       2014-08-24 21:26:39 +08:00
    >>> lst = [1,2,3,4,5,6,7,8]
    >>> zip(*[iter(lst)]*2)
    [(1, 2), (3, 4), (5, 6), (7, 8)]
    hit9
        10
    hit9  
       2014-08-24 21:27:48 +08:00
    starsoi
        11
    starsoi  
       2014-08-24 23:19:41 +08:00
    @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
        12
    hit9  
       2014-08-25 12:13:05 +08:00
    @starsoi 非常赞。你知道慢在哪里了吗?
    hit9
        13
    hit9  
       2014-08-25 12:20:44 +08:00
    两者的开销差貌似只有" 放到list中再unpack到args中"
    starsoi
        14
    starsoi  
       2014-08-25 16:51:45 +08:00
    @hit9 我的timeit多算了10000次的iter()的开销。。。把iter放到setup里就一样了

    >>> timeit('zip(*[b]*2)', setup='a=range(100000);b=iter(a)', number=10000)
    0.022448062896728516
    hit9
        15
    hit9  
       2014-08-26 10:35:56 +08:00
    @starsoi 是的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2839 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 07:30 · PVG 15:30 · LAX 23:30 · JFK 02:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.