有没有更有效的方式来做我目前正在做的事情?
我有一组列表值,名为headers
,将用于csv列标题。这些值与我正在解析的文件中的数据点名称一致。
例如:
headers = ['date', 'timeup', 'timedown', 'angle', 'flag']
文件的记录组间隔为20 *
,因此我将每个分隔分解成组:
>>> groups[0]:
['date=170821 timeup=3\ntimedown=5 angle=30\nflag=Y']
>>> groups[1]
['date=170821 timeup=13\ntimedown=25 angle=36\n']
我进一步解析得到元素对,以便:
for group in groups:
lines = [line for line in group.split('\n') if line and '=' in line]
items = [item.strip().split('=') for line in lines
for item in line.split(' ') if item]
得到:
>>>items[0]
[['date', 170821], ['timeup', 3], ['timedown', 5], ['angle', 30], ['flag', 'Y']]
>>>items[1]
[['date', 170821], ['timeup', 13], ['timedown', 25], ['angle', 6]]
现在要从中构建一个字典,并在元素不存在时填写'NULL'
,我正在做:
for group in groups:
d = {}
lines = [line for line in group.split('\n') if line and '=' in line]
items = [item.strip().split('=') for line in lines
for item in line.split(' ') if item]
for header in headers:
try:
x = [header in item for item in items].index(True)
d[header] = items[x][1]
except:
d[header] = 'NULL'
实际上这最终耗费时间,有时候我可以拥有超过800K组的groups
个对象,因此顶部for
已经在O(N)
运行; lines
和items
速度很快,但也分别在O(N)
和O(N^2)
运行(正确?)。然后,最后for
在O(N)
处运行。
总的来说,我有O(N) * O(N) * O(N^2) * O(N) = O(N^5)
而且那太糟糕了!
问题:
是否有更好的方法来确定所有
headers
元素是否作为items
子列表元素存在并构建dict()
?
我的店铺并不抱怨,因为它做的工作比以往任何时候都要快得多,但作为设计师,我知道这是有缺陷的(尽管只是因为数据点并不总是一致)。 / p>
答案 0 :(得分:1)
一种选择是使用更有效的方法来初始化dict
。此外,您可以将标题初始化为set
,然后检查填充的字典键集之间的差异,并填充缺少的字符串。
headers_set = set(headers)
for group in groups:
d = dict([x.split('=') for x in line.split() if '=' in line])
for missing_key in headers_set - set(d.keys()):
d[missing_key] = 'NULL'
根据%%timeit
测试,此方法在7.57μs内完成此循环,而您在上面提供的循环需要17μs才能执行。此代码也更像Pythonic恕我直言,似乎更容易解释。