如果模式与其他dict键匹配,Python dict键删除

时间:2012-10-18 20:29:04

标签: python design-patterns dictionary key

Python dict键删除,如果键模式与其他dict键匹配。

e.g。

a={'a.b.c.test':1,  'b.x.d.pqr':2,  'c.e.f.dummy':3,  'd.x.y.temp':4}

b={'a.b.c':1,  'b.p.q':20}

结果

a={'b.x.d.pqr':2,'c.e.f.dummy':3,'d.x.y.temp':4}`  

3 个答案:

答案 0 :(得分:3)

如果“模式匹配其他字典键”意味着“以其他字典中的任何键开头”,那么最直接的写法就是这样:

a = {k:v for (k, v) in a.items() if any(k.startswith(k2) for k2 in b)}

如果乍一看很难理解,那基本上相当于:

def matches(key1, d2):
    for key2 in d2:
        if key1.startswith(key2):
            return True
    return False

c = {}
for key in a:
  if not matches(key, b):
    c[key] = a[key]
a = c

这将比必要的慢。如果a有N个密钥,b有M个密钥,则所用时间为O(NM)。虽然您可以在固定时间内检查“dict k中是否存在密钥b”,但无法检查“dict k中是否存在以b开头的任何密钥”没有迭代整个字典。因此,如果b可能很大,您可能希望搜索sorted(b.keys())并编写二进制搜索,这将使时间缩短到O(N log M)。但如果这不是一个瓶颈,你可能最好坚持使用简单版本,因为它很简单。

请注意,我正在生成一个新的a并将匹配项筛选出来,而不是删除匹配项。由于多种原因,这几乎总是比原地删除更好的解决方案:  *理由更容易。将对象视为不可变对象并对它们执行纯操作意味着您无需考虑状态如何随时间变化。例如,在原地进行删除的简单方法会遇到一个问题,即你在迭代它时会改变字典,这会引发异常。没有可变操作的问题永远不会出现。  *它更容易阅读,并且(一旦你掌握它)甚至写。  *几乎总是更快。 (一个原因是,重复修改字典需要更多的内存分配和解除分配,而不是构建一个具有理解力的字典。)

一个权衡是内存使用。就地删除实现必须复制所有密钥; built-a-new-dict实现必须在内存中同时包含已过滤的dict和原始dict。如果您保留99%的值,并且值远大于键,则可能会对您造成伤害。 (另一方面,如果您保留10%的值,并且值与键大小相同,则实际上保存空间。)这就是为什么它“几乎总是“一个更好的解决方案,而不是”永远“。

答案 1 :(得分:1)

for key in list(a.keys()):
    if any(key.startswith(k) for k in b):
       del a[key]

key.startswith(k)替换为“匹配”的适当条件。

答案 2 :(得分:0)

c={} #result in dict c
for key in b.keys():
    if all([z.count(key)==0 for z in a.keys()]): #string of the key in b should not be substring for any of the keys in a
       c[key]=b[key]