首页 文章

将“元组列表”转换为平面列表或矩阵

提问于
浏览
43

使用Sqlite,“select..from”命令返回结果“output”,其打印(在python中):

>>print output
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]

它似乎是一个元组列表 . 我想在一个简单的1D数组中转换“输出”(我猜的是Python中的列表):

[12.2817, 12.2817, 0, 0, 8.52, 8.52]

或2x3矩阵:

12.2817 12.2817
0          0 
8.52     8.52

通过“output [i] [j]”读取

flatten命令不能完成第一个选项的工作,我不知道第二个选项...... :)

你能给我一个提示吗?有些事情很快就会很好,因为真正的数据要大得多(这里只是一个简单的例子) .

9 回答

  • 1

    到目前为止,发布的最快(和最短)解决方案:

    list(sum(output, ()))
    

    itertools 解决方案快约50%,比 map 解决方案快约70% .

  • 4

    在Python 3中,您可以使用 * 语法来展平迭代列表:

    >>> t = [ (1,2), (3,4), (5,6) ]
    >>> t
    [(1, 2), (3, 4), (5, 6)]
    >>> import itertools
    >>> list(itertools.chain(*t))
    [1, 2, 3, 4, 5, 6]
    >>>
    
  • 87

    列表理解方法适用于Iterable类型,并且比此处显示的其他方法更快 .

    flattened = [item for sublist in l for item in sublist]
    

    l 是要变平的列表(在OP的情况下称为 output


    timeit测试:

    l = list(zip(range(99), range(99)))  # list of tuples to flatten
    

    列表理解

    [item for sublist in l for item in sublist]
    

    timeit结果=每循环7.67μs±129 ns

    列出extend()方法

    flattened = []
    list(flattened.extend(item) for item in l)
    

    timeit结果=每循环11μs±433 ns

    sum()

    list(sum(l, ()))
    

    timeit结果=每个循环24.2μs±269 ns

  • 10

    使用 itertools 链:

    >>> import itertools
    >>> list(itertools.chain.from_iterable([(12.2817, 12.2817), (0, 0), (8.52, 8.52)]))
    [12.2817, 12.2817, 0, 0, 8.52, 8.52]
    
  • 6

    或者您可以像这样展平列表:

    reduce(lambda x,y:x+y, map(list, output))
    
  • 3

    另一个选项比大数组的sum选项更快:

    用map / extend展平:

    l = []
    list(map(l.extend, output))
    

    使用列表理解而不是 Map 展平(更快)

    l = []
    list(l.extend(row) for row in output)
    

    Update :使用extend展平但不理解且不使用列表作为迭代器(最快)

    在检查下一个答案后,通过列表理解提供了更快的解决方案 dual for 我做了一点调整,现在它表现得更好,首先执行list(...)拖动了很大一部分时间,然后更改了列表理解为一个简单的循环也削减了一点 . 最终的解决方案是:

    l = []
    for row in output: l.extend(row)
    

    通过删除[...]的列表(...)来获得新的扩展和改进的一些时间:

    import timeit
    t = timeit.timeit
    o = "output=list(zip(range(1000000000), range(10000000))); l=[]"
    steps_ext = "for row in output: l.extend(row)"
    steps_ext_old = "list(l.extend(row) for row in output)"
    steps_ext_remove_list = "[l.extend(row) for row in output]"
    steps_com = "[item for sublist in output for item in sublist]"
    
    print("new extend:      ", t(steps_ext, setup=o, number=10))
    print("old extend w []: ", t(steps_ext_remove_list, setup=o, number=10))
    print("comprehension:   ", t(steps_com, setup=o, number=10,))
    print("old extend:      ", t(steps_ext_old, setup=o, number=10))
    
    >>> new extend:       4.502427191007882
    >>> old extend w []:  5.281140706967562
    >>> comprehension:    5.54302118299529
    >>> old extend:       6.840151469223201
    
  • 4
    >>> flat_list = []
    >>> nested_list = [(1, 2, 4), (0, 9)]
    >>> for a_tuple in nested_list:
    ...     flat_list.extend(list(a_tuple))
    ... 
    >>> flat_list
    [1, 2, 4, 0, 9]
    >>>
    

    您可以轻松地从元组列表移动到单个列表,如上所示 .

  • 1

    在任意嵌套列表的情况下(以防万一):

    def flatten(lst):
        result = []
        for element in lst: 
            if hasattr(element, '__iter__'):
                result.extend(flatten(element))
            else:
                result.append(element)
        return result
    
    >>> flatten(output)
    [12.2817, 12.2817, 0, 0, 8.52, 8.52]
    
  • 5

    这就是 numpy 的用途,包括数据结构和速度方面 .

    import numpy as np
    
    output = [(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
    output_ary = np.array(output)   # this is your matrix 
    output_vec = output_ary.ravel() # this is your 1d-array
    

相关问题