我正在尝试编写一段代码,以从工作表中读取一些行(使用openpyxl),然后根据行中的数据和一个预先存在的列表(基于同一张表)创建一个列表。我创建了一个可以完成此工作的循环,但是当它获得更大的工作表文件时,它的速度太慢了。有没有办法使其更快?
biglist = []
rows = #some rows extracted from Excel with openpyxl
lists = [[1, 'E1000', 0], #this is just a small sample
[1, 'F1000', 0],
[1, 'G1000', 4],
[1, 'H1000', 3],
[1, 'I1000', 5],
[2, 'E1000', 1]]
for row in rows:
for cell in row:
smalllist =[]
smalllist.append(1)
smalllist.append(cell.coordinate)
style = 0
for l in lists:
for i,cl in enumerate(l):
if l[i][0] == smalllist[0] and l[i][1] == smalllist[1]:
style = l[i][2]
smalllist.append(style)
smalllist.append(cell.value)
biglist.append(smalllist)
真正减慢循环速度的是这个片段:
for l in lists:
for i,cl in enumerate(l):
if l[i][0] == smalllist[0] and l[i][1] == smalllist[1]:
style = l[i][2]
有没有办法加快速度?我已经尝试过使用地图和列表理解功能,但是速度并不快,甚至更慢。
答案 0 :(得分:1)
您没有显示styles
是什么,但可以尝试从中构建映射(映射几乎具有线性查找时间),因此您无需每次都遍历styles
。也就是说,假设这部分确实是代码的瓶颈(如您在问题中所述)。
您可以在循环之前构建一个dict
:
styles_dict = {
(cl[0], cl[1]): cl[2]
for cl in s
for s in styles}
并在外观中查找特定样式,如下所示:
style = styles_dict.get((smalllist[0], smalllist[1]))
if style is not None:
pass
对您有用吗?
答案 1 :(得分:1)
除了Ralf的答案(这确实是要做的第一件事)之外,还有其他两种可能的微观优化方法:
首先,不要仅将smalllist
创建为空,而是将其追加,而是直接填充(我假设您已经实现了Ralf的解决方案)-这样可以避免多次方法解析和调用的费用-然后使用别名{ {1}}和biglist.append
(同上,避免了不断重复进行方法解析的代价):
styles_dict.get
或编写一个辅助函数来创建“小列表”并使用列表理解:
biglist = []
# local alias
append = biglist.append
get_style = styles_dict.get
for row in rows:
for cell in row:
# avoids a double lookup
coords = cell.coordinate
append([1, coords, get_style((1, coords), 0), cell.value])
您可以使用def tranform(cell):
coords = cell.coordinate
return [1, coords, get_style((1, coords), 0), cell.value]
biglist = [transform(cell) for row in rows for cell in row]
模块来测试哪种解决方案更快。
答案 2 :(得分:0)
您可以使用dict
来查找样式,以前两列为键:
styles = {(1, 'E1000'): 0,
(1, 'F1000'): 0,
...}
然后像这样查找并应用您的样式...
key = (smalllist[0], smalllist[1])
style = styles[key]
对于大型样式列表,这应该更快一些,因为查找是恒定时间,而不是线性时间。
答案 3 :(得分:0)
您可以从dictionary
创建一个lists
并在字典中查找,而不必每次都在lists
上循环-
dict_keys = [(l[0], l[1]) for l in lists]
dict_values = [l[2] for l in lists]
dict_of_lists = { k:v for (k, v) in zip(dict_keys, dict_values) }
您还可以将内部for
循环替换为查找-
key = (smalllist[0], smallist[1])
try:
style = dict_of_lists[key]
except KeyError:
style = 0
答案 4 :(得分:-1)
尝试:
注意:以我的经验,您将编写更少的代码行,并且比传统的for循环运行得更快。