我的代码遇到效率问题,我试图将一个很长的列表折叠成一个较小的更可行的列表。
我正在从sql中获取数据,如下所示:
[a,1,2,3,4,5,6....]
[b,1,2,3,4,5,6....]
[b,1,2,3,4,5,6....]
[b,1,2,3,4,5,6....]
[c,1,2,3,4,5,6....]
[c,1,2,3,4,5,6....]
然后我将其变成:
[a,b,c] ->
[[a,1,2,...]]
[[b,1,2,...],[b,1,2,...],[b,1,2,...]]
[[c,1,2,...],[c,1,2,...]]
这是我正在生成的代码。
master = []
for x in range(0, len(unique_ids)):
master.append([])
z=0;
for y in range(0,len(mysql_return)):
if(unique_ids[x] == list(mysql_return[y])[0]):
master[x].append(list(mysql_return[y]))
问题在于,随着答复进入100的Ks中,这确实成倍下降。有更好的方法吗?
答案 0 :(得分:2)
IIUC
from itertools import groupby
from operator import itemgetter
first = itemgetter(0)
items = [['a', 1, 2, 3, 4, 5, 6],
['b', 1, 2, 3, 4, 5, 6],
['b', 1, 2, 3, 4, 5, 6],
['b', 1, 2, 3, 4, 5, 6],
['c', 1, 2, 3, 4, 5, 6],
['c', 1, 2, 3, 4, 5, 6]]
for k,v in groupby(items, key=first):
print(list(v))
[['a', 1, 2, 3, 4, 5, 6]]
[['b', 1, 2, 3, 4, 5, 6], ['b', 1, 2, 3, 4, 5, 6], ['b', 1, 2, 3, 4, 5, 6]]
[['c', 1, 2, 3, 4, 5, 6], ['c', 1, 2, 3, 4, 5, 6]]
items
是您的列表列表。
您还可以将其存储在字典中
d = {}
for k,v in groupby(items, key=first):
d[k] = list(v)
{'a': [['a', 1, 2, 3, 4, 5, 6]],
'b': [['b', 1, 2, 3, 4, 5, 6],
['b', 1, 2, 3, 4, 5, 6],
['b', 1, 2, 3, 4, 5, 6]],
'c': [['c', 1, 2, 3, 4, 5, 6],
['c', 1, 2, 3, 4, 5, 6]]}
注意事项:数据必须先进行排序
sorted(items, key=first)
答案 1 :(得分:1)
您的原始代码中的Nothing看起来应该表现出任何形式的指数减慢。 append
是(摊销的)O(1)操作,只需要定期扩展基础数组。就是说,我将做一些更改:
按原样使用mysql_return[y]
,而无需创建新列表。如果出于某种原因需要而不是原始元组,则无需创建列表。
您使用x
的唯一原因是对unique_ids
的只读访问权限;只需直接遍历值即可。您不需要它来索引master
;您总是想追加到master
的最后一个元素,您可以用master[-1]
来引用它。
y
也是如此;您只能将其用于对mysql_return
的只读访问。
master = []
for unique_id in unique_ids:
master.append([])
for sql in mysql_return:
sql = list(sql) # Possibly unnecessary
if unique_id == sql[0]:
master[-1].append(sql)
事实上,整个内部循环可以用单个列表理解替换,结果列表在事实之后附加到master
。
master = []
for unique_id in unique_ids:
master.append([list(x) for x in mysql_return if x[0] == unique_id])
剩下的循环也可以 替换为列表理解。
master = [[list(x) for x in mysql_return if x[0] == unique_id] for unique_id in unique_ids]