比较dict值并弹出键

时间:2016-11-10 13:53:17

标签: python dictionary comparison

我有一个大字典,简化如下:

my_dict = {'a': [-33.27, -2.12, 5.23], 'b': [-57.11, 9.82, -26.13], ...}

所以键是字符串,值是浮点数列表。

我想要做的是通过运行查找和删除一些冗余键:值对的标准来减小它的大小。

伪代码中的标准是:

对于每个键i,

,查找dict中是否存在不同的键j,以便:

  • value_of_key_i[0] > value_of_key_j[0] and
  • value_of_key_i[1] > value_of_key_j[1] and
  • abs(value_of_key_i[2]) < abs(value_of_key_j[2])

我为此任务写的是:

to_remove = []
for ilcs, iloads in running_load.items():
    for jlcs, jloads in running_load.items():
        if iloads[0] > jloads[0] and iloads[1] > jloads[1] and abs(iloads[2]) < abs(jloads[2]):
            # print(iloads, jloads)
            to_remove.append(ilcs)
            break

for i in to_remove:
    running_load.pop(i)

哪个确实有效,但显式遍历dict两次并且弹出的必要额外for循环感觉效率低下..

有更好的方法吗?使用生成器执行此操作会更有效吗,让我们说any()

PS:我的方法的另一个问题是它无法测试相等性,因为在某些时候将对自己测试值(是的,可以检查它和continue但是......)< / p>

2 个答案:

答案 0 :(得分:0)

您可以创建一个新词典,只添加要保留的元素,而不是使用要删除的元素列表。

我没有真正看到在初始阶段降低O(n ^ 2)复杂度的方法(将每个元素与其他所有元素进行比较),但如上所述,排序将有所帮助。

此外,我认为您将生成两个不同的列表,其中包含字典中的相同内容(每个列表中的一个列表)。与&#34相比,这不应该算得太多;将每个项目与其他项目进行比较&#34;,但它仍然有帮助。

答案 1 :(得分:0)

所以沿着最初的也许是最明显的解决方案(algo1)我写了第二个(algo2):

  • 从dict创建一个元组列表。
  • 命令它(因此将比较减少到2)。
  • 切片(从而减少从n ^ 2到(n ^ 2 + n)/ 2的比较 - &gt; n越大,优势越大
  • 并弹出相同的循环。
def algo1(a_dict):
    to_remove = []
    for ilcs, iloads in a_dict.items():
        for jlcs, jloads in a_dict.items():
            if iloads[0] > jloads[0] and iloads[1] > jloads[1] and abs(iloads[2]) < abs(jloads[2]):
                # print(iloads, jloads)
                to_remove.append(ilcs)
                break
    for i in to_remove:
        a_dict.pop(i)
    return a_dict

def algo2(a_dict):
    ordered_list_view = sorted(a_dict.items(), key=lambda t: abs(t[1][2]))
    for i, ikv in enumerate(ordered_list_view):
        forward_slice = ordered_list_view[i:]
        for j, jkv in enumerate(forward_slice):
            if all(ikv[1][j] > jkv[1][j] for j in range(2)):
                print(ikv[1], jkv[1])
                a_dict.pop(ikv[0])
                break
    return a_dict

我也把他们计时但令我惊讶的是,algo1仍然更快。边缘,但仍然..