【问题标题】:Converting a list of lists to a tuple in Python在 Python 中将列表列表转换为元组
【发布时间】:2010-12-25 10:54:15
【问题描述】:

我有一个列表列表(通过简单的列表理解生成):

>>> base_lists = [[a, b] for a in range(1, 3) for b in range(1, 6)]
>>> base_lists

[[1,1],[1,2],[1,3],[1,4],[1,5],[2,1],[2,2],[2,3],[2,4],[2,5]]

我想把整个列表变成一个包含列表中所有值的元组,即:

resulting_tuple = (1,1,1,2,1,3,1,4,1,5,2,1,2,2,2,3,2,4,2,5)

最有效的方法是什么? (使用列表理解生成相同元组的方法也是一个可以接受的答案。)我已经在此处和 Python 文档中查看了答案,但是我一直找不到合适的答案。

编辑:

非常感谢所有回答的人!

【问题讨论】:

    标签: python list-comprehension itertools tuple-packing


    【解决方案1】:
    tuple(x for sublist in base_lists for x in sublist)
    

    编辑:请注意,base_lists 如此短,genexp(可用内存无限)很慢。考虑以下文件tu.py

    base_lists = [[a, b] for a in range(1, 3) for b in range(1, 6)]
    
    def genexp():
      return tuple(x for sublist in base_lists for x in sublist)
    
    def listcomp():
      return tuple([x for sublist in base_lists for x in sublist])
    
    def withsum():
      return tuple(sum(base_lists,[]))
    
    import itertools as it
    
    def withit():
      return tuple(it.chain(*base_lists))
    

    现在:

    $ python -mtimeit -s'import tu' 'tu.genexp()'
    100000 loops, best of 3: 7.86 usec per loop
    $ python -mtimeit -s'import tu' 'tu.withsum()'
    100000 loops, best of 3: 5.79 usec per loop
    $ python -mtimeit -s'import tu' 'tu.withit()'
    100000 loops, best of 3: 5.17 usec per loop
    $ python -mtimeit -s'import tu' 'tu.listcomp()'
    100000 loops, best of 3: 5.33 usec per loop
    

    当列表更长时(即,当性能真的很重要时)情况会有所不同。例如,将 100 * 放在定义 base_lists 的 RHS 上:

    $ python -mtimeit -s'import tu' 'tu.genexp()'
    1000 loops, best of 3: 408 usec per loop
    $ python -mtimeit -s'import tu' 'tu.withsum()'
    100 loops, best of 3: 5.07 msec per loop
    $ python -mtimeit -s'import tu' 'tu.withit()'
    10000 loops, best of 3: 148 usec per loop
    $ python -mtimeit -s'import tu' 'tu.listcomp()'
    1000 loops, best of 3: 278 usec per loop
    

    所以对于长列表,只有 withsum 是性能灾难——其他人在同一个球场,尽管显然 itertools 具有优势,并且列表理解(当有足够的内存可用时,它总是会在microbenchmarks;-) 比 genexps 更快。

    使用1000 *,genexp 减慢了大约 10 倍(wrt the 100 *),withit 和 listcomp 减慢了大约 12 倍,withsum 减慢了大约 180 倍(withsum 是 O(N squared),而且它开始受到影响严重的堆碎片)。

    【讨论】:

    • 正是我需要的。谢谢亚历克斯!
    【解决方案2】:
    from itertools import chain
    base_lists = [[a, b] for a in range(1, 3) for b in range(1, 6)]
    
    print tuple(chain(*base_lists))
    

    【讨论】:

    • 投票赞成使用itertools,这是一个被低估的模块
    【解决方案3】:
    >>> sum(base_lists,[])
    [1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5]
    >>> tuple(sum(base_lists,[]))
    (1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5)
    

    【讨论】:

    • sum 用于除数字之外的任何东西都是一个坏主意(正如我经常尝试在 SO 中解释的那样——我是 Python 的 sum 的创始人,所以每当我感到内疚时我看到它被滥用了;-)。提示:O(N 平方)。
    • 哎呀,很高兴知道谢谢亚历克斯。我想它不可能是 O(N) 有一个很好的理由:/
    【解决方案4】:

    resulting_tuple = tuple(item for l in base_lists for item in l)

    【讨论】:

      【解决方案5】:
      >>> arr=[]
      >>> base_lists = [[a, b] for a in range(1, 3) for b in range(1, 6)]
      >>> [ arr.extend(i) for i in base_lists ]
      [None, None, None, None, None, None, None, None, None, None]
      >>> arr
      [1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5]
      >>> tuple(arr)
      (1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-27
        • 2021-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-01
        • 2017-09-11
        相关资源
        最近更新 更多