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

gar*_*rth 57 python tuples list

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

>>print output
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
Run Code Online (Sandbox Code Playgroud)

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

[12.2817, 12.2817, 0, 0, 8.52, 8.52]
Run Code Online (Sandbox Code Playgroud)

或2x3矩阵:

12.2817 12.2817
0          0 
8.52     8.52
Run Code Online (Sandbox Code Playgroud)

通过"output [i] [j]"读取

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

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

Joe*_*ett 101

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

list(sum(output, ()))
Run Code Online (Sandbox Code Playgroud)

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

  • 好的,我应该阅读手册*g*.似乎`sum(sequence [,start])`:sum添加`start`,默认为'0`而不是从`sequence [0]`开始,如果它存在,然后添加其余的元素.对不起,打扰你. (9认同)
  • @Joel很好,但我想知道它是如何工作的?`list(output [0] + output [1] + output [2])`给出了所需的结果,但`list(sum(output))`没有.为什么?()做什么"魔术"? (6认同)
  • 是的,快但完全钝.你必须留下评论它实际上在做什么:( (5认同)
  • 这是一个众所周知的反模式:不要使用“ sum”来连接序列,这会导致二次时间算法。的确,如果您尝试使用字符串来执行`sum`函数,它将发出抱怨! (2认同)

Gma*_*man 22

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

flattened = [item for sublist in l for item in sublist]
Run Code Online (Sandbox Code Playgroud)

l是扁平化的列表(output在OP的情况下称为)


时间测试:

l = list(zip(range(99), range(99)))  # list of tuples to flatten
Run Code Online (Sandbox Code Playgroud)

列表理解

[item for sublist in l for item in sublist]
Run Code Online (Sandbox Code Playgroud)

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

列出extend()方法

flattened = []
list(flattened.extend(item) for item in l)
Run Code Online (Sandbox Code Playgroud)

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

和()

list(sum(l, ()))
Run Code Online (Sandbox Code Playgroud)

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

  • 我必须在大型数据集上使用它,列表理解方法是迄今为止最快的! (2认同)

Thr*_*ton 16

在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]
>>> 
Run Code Online (Sandbox Code Playgroud)


Mar*_*ina 7

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

reduce(lambda x,y:x+y, map(list, output))
Run Code Online (Sandbox Code Playgroud)


Cha*_*tie 7

使用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]
Run Code Online (Sandbox Code Playgroud)


Tot*_*oro 6

更新:使用扩展但不理解且不使用列表作为迭代器进行展平(最快)

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

新的解决方案是:

l = []
for row in output: l.extend(row)
Run Code Online (Sandbox Code Playgroud)

较旧:

使用地图/扩展进行展平:

l = []
list(map(l.extend, output))
Run Code Online (Sandbox Code Playgroud)

使用列表理解而不是地图进行展平

l = []
list(l.extend(row) for row in output)
Run Code Online (Sandbox Code Playgroud)

只需删除[...]的list(...),就可以进行一些新扩展和改进:

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    
Run Code Online (Sandbox Code Playgroud)


cob*_*bie 5

>>> 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]
>>> 
Run Code Online (Sandbox Code Playgroud)

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


Jos*_*ook 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
Run Code Online (Sandbox Code Playgroud)