在Python

时间:2016-07-30 21:32:11

标签: python list for-loop dictionary iteration

---编辑2 --- 所以我得到的问题为什么我使用字典? 这个问题是对此问题的跟进:csv file compression without using existing libraries in Python

我需要压缩500k csv文件(19MB),我选择使用字典将刻度存储在一个csv文件中,将symbs存储在另一个csv文件中以便能够解压缩值

问题:如何迭代最优化的方式?这只是一个4行的例子,但是我的真实文件有500 000行,并且让我永远遍历列表。

我有3个词典:

originalDict = {
               0: ['6NH8', 'F', 'A', '0', '60541567', '60541567', '78.78', '20'], 
               1: ['6NH8', 'F', 'A', '0', '60541569', '60541569', '78.78', '25'], 
               2: ['6AH8', 'F', 'B', '0', '60541765', '60541765', '90.52', '1'], 
               3: ['QMH8', 'F', 'B', '0', '60437395', '60437395', '950.5', '1']
               }
ticks = {0: '6NH8', 1: '6AH8', 2: 'QMH8'}
symbs = {0: 'F,A', 1: 'F,B'}

我想遍历originalDict并更改" ticks"然后是index 1index 2处的符号,然后删除index 2

所以,即

0: ['6NH8', 'F', 'A', '0', '60541567', '60541567', '78.78', '20']

变为:

[0, '0', '0', '60541567', '60541567', '78.78', '20']

我目前有一个for循环遍历originalDict中的值,并且在另一个for循环中:

for values in originalDict.values():
    for ticksKey, ticksValue in ticks.items():
        if values[0] == ticksValue:
            values[0] = ticksKey

    #Change symbs and remove char combination
    for symbsKey, symbsValue in symbs.items():
        comprComb = values[1] + "," + values[2]

        if comprComb == symbsValue:
            values[1] = str(symbsKey)
            #del values[4]
            #del values[4]
            del values[2]

增加的附加信息: 我把它们作为字典的原因是因为500 000行,一些刻度不止一次出现,所以,我给它们一个int,这是dict中的关键,所以也适用于symbs字典。

3 个答案:

答案 0 :(得分:1)

首先,你想要反转映射,你当前正在寻找值,这是错误的和缓慢的:

ticks = {0: '6NH8', 1: '6AH8', 2: 'QMH8'}
symbs = {0: 'F,A', 1: 'F,B'}

使用ticks = {v: k for k, v in ticks.items()}symbs相同):

{'6NH8': 0, 'QMH8': 2, '6AH8': 1} # ticks

{'F,A': 0, 'F,B': 1} # symbs

现在您拥有良好的数据结构,您可以相当快地完成此任务。

现在将保存数据的字典转换为列表(不确定为什么它是一个字典开头):

originalList = [originalDict[k] for k in range(len(originalDict))]

重新映射值:

for line in originalList:
    line[0] = ticks[line[0]]
    line[1:3] = [symbs["%s,%s" % tuple(line[1:3])]]

结果:

[[0, 0, '0', '60541567', '60541567', '78.78', '20'], [0, 0, '0', '60541569', '60541569', '78.78', '25'], [1, 1, '0', '60541765', '60541765', '90.52', '1'], [2, 1, '0', '60437395', '60437395', '950.5', '1']]

答案 1 :(得分:0)

您可以通过反转tickssymbs dicts中的键和值来加速查找,然后只需查找正确的值而不是迭代并比较dicts中的所有值:< / p>

ticks_inv = {v: k for k, v in ticks.items()}
symbs_inv = {v: k for k, v in symbs.items()}

for values in originalDict.values():
    if values[0] in ticks_inv:
        values[0] = ticks_inv[values[0]]

    comprComb = "{v[1]},{v[2]}".format(v=values)
    if comprComb in symbs_inv:
        values[1] = symbs_inv[comprComb]
        del values[2]

结果与您的代码相同,但速度要快得多,尤其是tickssymbs较大时。当然,这假设值是唯一的,但是否则你的代码将无法正常运行。

答案 2 :(得分:0)

你的词典是倒退的;它没有使用字典的键查找功能。而不是

for ticksKey, ticksValue in ticks.items():
    if values[0] == ticksValue:
        values[0] = ticksKey

ticks = {'6NH8': 0, '6AH8': 1, 'QMH8': 2}
...
if values[0] in ticks:
    values[0] = ticks[values[0]]

看起来有点奇怪只是

values[0] = ticks[values[0]] or values[0]

如果您这样做,并且类似于symbs,您将删除除必要的最外层循环之外的所有内容,并看到显着的性能提升。