您可以使用集合,如果值与集合不相交,则保持对:
st = {'2', '4', '17', '21', '22', '24', '27', '28', '29', '33', '39'}
filtered_dict = {k: v for (k, v) in my_dict.iteritems() if not st.isdisjoint(v)}
只有在不共享至少一个元素时,它们才会不相交:
In [6]: st ={1,2,3}
In [7]: v = [1,4,5]
In [8]: st.isdisjoint(v)
Out[8]: False
In [11]: v = [7,4,5]
In [12]: st.isdisjoint(v)
Out[12]: True
有点等价于:
st = {'2', '4', '17', '21', '22', '24', '27', '28', '29', '33', '39'}
filtered_dict = {k: v for (k, v) in my_dict.iteritems() if any(val in st for val in v)}
如果来自 v 的 any 元素在集合中,我们将保留这些元素。
在最坏的情况下,我们检查 len(v) 元素与集合,迭代 mylist 元素并检查 x 是否在 v 中为 O(len(my_list)) 对于每种情况,并且每次获得 a 时都会创建相同的 k,v 配对匹配。
如果我们添加一个带有更多匹配键的 dict 并将这些对添加到一个列表中,你可以看到会发生什么:
In [22]: my_list = ['2', '4', '17', '21', '22', '24', '27', '28', '29', '33', '39']
In [23]: my_dict = {'217': {'586': 2.0, '578': 5.0, '172': 1.0, '1222': 1.0, '597': 4.0, '1303': 2.0, '195': 5.0},
....: '660': {'176': 4.0, '174': 3.0, '231': 5.0, '233': 4.0, '797': 4.0, '541': 3.0, '27': 1.0, '210': 4.0},
....: '661': {'2': 4.0, '4': 3.0, '29': 5.0, '17': 4.0, '39': 4.0, '541': 3.0, '27': 1.0, '210': 4.0}}
In [24]: print [(k,v) for k,v in my_dict.iteritems() for x in my_list if x in v]
[('661', {'541': 3.0, '39': 4.0, '2': 4.0, '4': 3.0, '17': 4.0, '210': 4.0, '27': 1.0, '29': 5.0}), ('661', {'541': 3.0, '39': 4.0, '2': 4.0, '4': 3.0, '17': 4.0, '210': 4.0, '27': 1.0, '29': 5.0}), ('661', {'541': 3.0, '39': 4.0, '2': 4.0, '4': 3.0, '17': 4.0, '210': 4.0, '27': 1.0, '29': 5.0}), ('661', {'541': 3.0, '39': 4.0, '2': 4.0, '4': 3.0, '17': 4.0, '210': 4.0, '27': 1.0, '29': 5.0}), ('661', {'541': 3.0, '39': 4.0, '2': 4.0, '4': 3.0, '17': 4.0, '210': 4.0, '27': 1.0, '29': 5.0}), ('661', {'541': 3.0, '39': 4.0, '2': 4.0, '4': 3.0, '17': 4.0, '210': 4.0, '27': 1.0, '29': 5.0}), ('660', {'797': 4.0, '27': 1.0, '541': 3.0, '210': 4.0, '176': 4.0, '174': 3.0, '231': 5.0, '233': 4.0})]
因为有 7 次匹配,所以我们得到了 7 次相同的配对,您不会在 dict 中得到欺骗,但您必须迭代 len(my_list) 次并创建 x in v 的配对长度为 True 次。随着 my_list 长度的增加,运行时间也会相应增加。
只是让 my_list 1000 个元素有很大的不同:
In [35]: len(my_list)
Out[35]: 1000
In [36]: %%timeit
....: st = set(my_list)
....: {k: v for (k, v) in my_dict.iteritems() if not st.isdisjoint(v)}
....:
10000 loops, best of 3: 21.9 µs per loop
In [37]: timeit {k:v for k,v in my_dict.iteritems() for x in my_list if x in v}
10000 loops, best of 3: 136 µs per loop
几乎所有时间都花在了集合的创建上,如果你从一开始就使用一个集合,它的运行速度会快 100 倍:
In [40]: timeit {k: v for (k, v) in my_dict.iteritems() if not st.isdisjoint(v)}
1000000 loops, best of 3: 1.09 µs per loop