Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Subtract a list of dicts from another

I'm interested in comparing multiple lists, taking the difference and iterating through that.

Both are list of dicts that contain the following keys: 'ssid' - str, 'bssid' - str, 'channel' - int, 'flags' - list, 'found' - bool

I've tried:

 list = list(set(networks_list).difference(missing_networks))

But I receive the error:

unhashable type 'dict'

My data structure looks like this:

list: [{'found': False, 'flags': ['WPA2-PSK-CCMP', 'WPS', 'ESS'], 'ssid': 'SOHO_BROADCAST', 'bssid': '30:46:9a:9d:11:1a', 'channel': 1}, {'found': False, 'flags': ['WPA-EAP-TKIP', 'WPA2-EAP-CCMP', 'ESS'], 'ssid': 'Cisco 2.4ghz', 'bssid': '40:f4:ec:7f:3c:5a', 'channel': 11}, {'found': False, 'flags': ['WPA-EAP-TKIP', 'WPA2-EAP-CCMP', 'ESS'], 'ssid': 'Cisco 5.0ghz', 'bssid': '40:f4:ec:7f:3c:54', 'channel': 149}]

Missing networks is initially empty.

Is there a simple way of doing this?

like image 378
Parth Avatar asked Dec 02 '22 21:12

Parth


2 Answers

There are probably many pitfalls to a generic approach like this, but if your dictionaries are of mostly primitives, and not huge, you can do something like this:

Assuming your data looks something like this:

networks = [
        {'address': '192.168.1.1'},
        {'address': '127.0.0.1'},
    ]

missing = [
        {'address': '127.0.0.1'}
    ]

You can turn the lists of dictionaries into lists tuples (which are hashable)

def make_hashable(d):
    return (frozenset(x.iteritems()) for x in d)

networks_hashable = make_hashable(networks)
missing_hashable = make_hashable(missing)

Then subtract

diff = set(networks_hashable).difference(missing_hashable)

Now you have a list of tuples

print list(diff)

or, convert back to dictionaries

print [dict(x) for x in diff]

Update

I've changed the definition of make_hashable based on @gnibbler's comment.

like image 73
Adam Wagner Avatar answered Dec 17 '22 22:12

Adam Wagner


Instead of making them list of dicts make them a list of objects which implement __eq__ and __hash__ and the code you provide should work

like image 31
Doboy Avatar answered Dec 17 '22 23:12

Doboy