列表元素中的Dict() - 减少时间复杂度

时间:2017-08-21 13:10:29

标签: python python-3.x

有没有更有效的方式来做我目前正在做的事情?

我有一组列表值,名为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)运行; linesitems速度很快,但也分别在O(N)O(N^2)运行(正确?)。然后,最后forO(N)处运行。

总的来说,我有O(N) * O(N) * O(N^2) * O(N) = O(N^5)而且那太糟糕了!

问题:

  

是否有更好的方法来确定所有headers元素是否作为items子列表元素存在并构建dict()

我的店铺并不抱怨,因为它做的工作比以往任何时候都要快得多,但作为设计师,我知道这是有缺陷的(尽管只是因为数据点并不总是一致)。 / p>

1 个答案:

答案 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恕我直言,似乎更容易解释。