使用 Sqlite,
select .. from
命令返回结果 output
,打印:
>>print output
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
它似乎是一个元组列表。我想将
output
转换为简单列表:
[12.2817, 12.2817, 0, 0, 8.52, 8.52]
或 2x3 矩阵:
12.2817 12.2817
0 0
8.52 8.52
通过
output[i][j]
阅读
拼合命令不能完成第一个选项的工作,我不知道第二个选项......
快速解决方案将不胜感激,因为实际数据要大得多。
迄今为止发布的最快(也是最短)的解决方案:
list(sum(output, ()))
比
itertools
解决方案快约 50%,比 map
解决方案快约 70%。
列表理解方法适用于可迭代类型,并且比此处显示的其他方法更快。
flattened = [item for sublist in l for item in sublist]
l
是要展平的列表(在OP的情况下称为output
)
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 每个循环
flattened = []
list(flattened.extend(item) for item in l)
timeit 结果 = 11 µs ± 433 ns 每个循环
list(sum(l, ()))
timeit 结果 = 24.2 µs ± 269 ns 每个循环
在 Python 2.7 和 Python3 的所有版本中,您可以使用
itertools.chain
来展平可迭代列表。使用 *
语法或类方法。
>>> 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]
>>> list(itertools.chain.from_iterable(t))
[1, 2, 3, 4, 5, 6]
更新:使用扩展进行扁平化,但没有理解,并且不使用列表作为迭代器(最快)
在检查了下一个答案后,通过列表理解提供了更快的解决方案
dual for
我做了一些调整,现在它表现更好,首先 list(...) 的执行拖了很大一部分时间,然后更改一个简单循环的列表理解,也减少了一些。
新的解决方案是:
l = []
for row in output: l.extend(row)
旧的将
list
替换为[]
(慢一点但不多):
[l.extend(row) for row in output]
年长(较慢):
通过列表理解进行扁平化
l = []
list(l.extend(row) for row in output)
新扩展的一些时间以及通过删除 [...] 的 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(f"{steps_ext}\n>>>{t(steps_ext, setup=o, number=10)}")
print(f"{steps_ext_remove_list}\n>>>{t(steps_ext_remove_list, setup=o, number=10)}")
print(f"{steps_com}\n>>>{t(steps_com, setup=o, number=10)}")
print(f"{steps_ext_old}\n>>>{t(steps_ext_old, setup=o, number=10)}")
计算结果:
for row in output: l.extend(row)
>>> 7.022608777000187
[l.extend(row) for row in output]
>>> 9.155910597999991
[item for sublist in output for item in sublist]
>>> 9.920002304000036
list(l.extend(row) for row in output)
>>> 10.703829122000116
>>> 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]
>>>
您可以轻松地从元组列表移动到单个列表,如上所示。
使用
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]
或者你可以像这样展平列表:
reduce(lambda x,y:x+y, map(list, output))
从数据结构和速度角度来看,这就是
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
如果是任意嵌套列表(以防万一):
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]
def flatten_tuple_list(tuples):
return list(sum(tuples, ()))
tuples = [(5, 6), (6, 7, 8, 9), (3,)]
print(flatten_tuple_list(tuples))
问题提到元组列表(
output
)是由Sqlite select .. from
命令返回的。
您可以使用
output
调整sqlite连接返回行的方式,以返回带有数值的矩阵(列表/嵌套列表的列表)而不是带有元组的列表,而不是展平返回的row_factory
:
import sqlite3 as db
conn = db.connect('...')
conn.row_factory = lambda cursor, row: list(row) # This will convert the tuple to list.
c = conn.cursor()
output = c.execute('SELECT ... FROM ...').fetchall()
print(output)
# Should print [[12.2817, 12.2817], [0, 0], [8.52, 8.52]]