Python字典理解很慢

Dav*_*agh 13 python dictionary list

我有一本字典d1和一份清单l1.

字典键是字符串,值是我自己定义的对象.如果它有帮助,我可以更详细地描述对象,但是现在,对象具有列表属性names,并且name可能会或可能不会出现一些元素l1.

我想要做的是扔掉字典中的任何元素d1,其中name所述元素中的对象的属性不包含任何出现的元素l1.

作为一个简单的例子:

l1 = ['cat', 'dog', 'mouse', 'horse', 'elephant', 
      'zebra', 'lion', 'snake', 'fly']

d1 = {'1':['dog', 'mouse', 'horse','orange', 'lemon'],
      '2':['apple', 'pear','cat', 'mouse', 'horse'], 
      '3':['kiwi', 'lime','cat', 'dog', 'mouse'], 
      '4':['carrot','potato','cat', 'dog', 'horse'], 
      '5':['chair', 'table', 'knife']}
Run Code Online (Sandbox Code Playgroud)

所以造成词典将或多或少相同,但每个列表的元素将是关键-值对来自14不包括水果和蔬菜,将不包含5键值面值为无值出现在家具l1.

为此,我使用了嵌套列表/字典理解,如下所示:

d2 = {k: [a for a in l1 if a in d1[k]] for k in d1.keys()}
print(d2)

>>>>{'1': ['dog', 'mouse', 'horse'], 
     '3': ['cat', 'dog', 'mouse'], 
     '2': ['cat', 'mouse', 'horse'], 
     '5': [], 
     '4': ['cat', 'dog', 'horse']}

d2 = {k: v for k,v in d2.iteritems() if len(v)>0}
print(d2)

>>>>{'1': ['dog', 'mouse', 'horse'], 
     '3': ['cat', 'dog', 'mouse'], 
     '2': ['cat', 'mouse', 'horse'],  
     '4': ['cat', 'dog', 'horse'],}
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但对于大型词典,7000多个项目,需要大约20秒才能完成.本身并不可怕,但我需要在一个循环中执行此操作,该循环将迭代10,000次,因此目前它不可行.有关如何快速完成此任务的任何建议?

Jol*_*per 14

您正在有效地计算字典值中出现的每个列表与列表的集合交集l1.由于涉及线性搜索,因此使用用于集合交叉的列表是相当低效的.您应该l1转换为集合并使用set.intersection()或设置成员资格测试(取决于结果是否为可接受的可接受).

完整代码可能如下所示:

l1 = set(l1)
d2 = {k: [s for s in v if s in l1] for k, v in d1.iteritems()}
d2 = {k: v for k, v in d2.iteritems() if v}
Run Code Online (Sandbox Code Playgroud)

for在这里使用单个循环也可能更好,而不是两个字典理解:

l1 = set(l1)
d2 = {}
for k, v in d1.iteritems():
    v = [s for s in v if s in l1]
    if v:
        d2[k] = v
Run Code Online (Sandbox Code Playgroud)