comparing two lists
Peter Otten
__peter__ at web.de
Thu Aug 23 17:53:53 EDT 2007
Ladislav Andel wrote:
> Peter Otten wrote:
>> Ladislav Andel wrote:
>>
>>
>>> what would be the most efficient way to do following?
>>>
>>> I have a list of dictionaries taken from DB e.g.
>>> dblist = [{'id:1, 'host':'google.com','ip_address':'1.2.3.4'},
>>> {'id:3, 'host':'yahoo.com','ip_address':'5.6.7.8'},
>>> {'id:9, 'host':'msn.com','ip_address':'11.3.2.3'}]
>>>
>>> and list of object instances in memory(it's just for example)
>>> which are looping within itself and testing particular hosts
>>>
>>> memlist = [<instance 1>,<instance 2>]
>>> memlist[0].id is 1 and memlist[0].host is google.com etc.
>>> memlist[1].id is 9 and memlist[1].host is msn.com etc.
>>>
>>> Now I want to add a new instance to memlist since id=3(in dblist) is not
>>> in memlist.
>>> How would you iterate through it and insert a new instance?
>>>
>>> The result should be:
>>> memlist = [<instance 1>,<instance 2>, <instance 3>]
>>> memlist[0].id is 1 and memlist[0].host is google.com etc.
>>> memlist[1].id is 3 and memlist[1].host is yahoo.com etc.
>>> memlist[2].id is 9 and memlist[2].host is msn.com etc.
>>>
>>
>> You should replace the memlist with a dictionary using (host, id) tuples
>> as the keys. Here's an example that uses a set but requires you to modify
>> the <instance N> class:
>>
>> dblist = [{'id':1, 'host':'google.com','ip_address':'1.2.3.4'},
>> {'id':3, 'host':'yahoo.com','ip_address':'5.6.7.8'},
>> {'id':9, 'host':'msn.com','ip_address':'11.3.2.3'}]
>>
>> class Item(object):
>> def __init__(self, id, host, **discarded):
>> self._tuple = (id, host)
>> def __hash__(self):
>> return hash(self._tuple)
>> def __eq__(self, other):
>> return self._tuple == other._tuple
>> def __repr__(self):
>> return "Item(id=%r, host=%r)" % self._tuple
>>
>> items = set([Item(1, "google.com")])
>> for d in dblist:
>> item = Item(**d)
>> if item not in items:
>> print "adding", item
>> items.add(item)
>> else:
>> print item, "already there"
>>
>>
> Thank you for this nice solution. I wouldn't be able to write it this
> way at all
Then think twice before you use it. The dictionary approach should be
straightforward.
> but what about removing from memlist if there is less items in dblist
> than in items (instances)?
> I will have to iterate over items(instances) and remove that one which
> is not in dblist I guess.
Yes, but again, if you use a dictionary instead of a list the lookup will be
efficient.
To follow up on my previous post: with sets there is a concise spelling:
items &= set(Item(**d) for d in dblist)
or even
items.intersection_update(Item(**d) for d in dblist)
if you don't mind object identity.
Peter
More information about the Python-list
mailing list