Filter a dictionary by multiple values

I'm new to Python, and I had a tough time when I developed the "pythony" way of filtering the dictionary.

I have a dictionary that looks like this:

'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, ...}

etc.

Then I have a list of lines:

['2', '4', '17', '21', '22', '24', '27', '28', '29', '33', '39', ...]

What I want to achieve is a filtered dictionary in which there are only tuples with any values ​​in the list of strings. I managed to do just that, but using only one line as a requirement, and it looks like this:

filtered_dict = {k: v for (k, v) in my_dict.iteritems() if my_list[0] in v}

However, if I delete [0], I get the following error:

TypeError: unhashable type: 'list' Here are some expected output values:

'115 : {'174': 4.0, '172': 4.0, '27': 3.0, '183': 5.0, '180': 3.0, '1039': 5.0, ... }

'212' : {'4': 3.0, '473': 4.0, '208': 5.0, '123': 4.0, '476': 3.0, '474': 4.0, ...}

As you can see, the third value in the first tuple has "27" in it, which was in my_list. The first value in the second tuple has the value "4", which was also in my_list.

.

!

+4
2

, , :

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)}

, any v , .

len(v) , mylist , x v O(len(my_list)) , 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 , , 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
+4

, mylist mydict

{k:v for k,v in mydict.iteritems() for x in mylist if x in v}

1) k: v k, v mydict.iteritems() .

2) x mylist, x v mylist , mylist in v, x in v x in v.keys(), x v

+3

All Articles