comparing two lists

Peter Otten __peter__ at
Thu Aug 23 23:53:53 CEST 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':'','ip_address':''},
>>> {'id:3, 'host':'','ip_address':''},
>>> {'id:9, 'host':'','ip_address':''}]
>>> 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 etc.
>>> memlist[1].id  is 9 and  memlist[1].host is 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 etc.
>>> memlist[1].id  is 3 and  memlist[1].host is etc.
>>> memlist[2].id  is 9 and  memlist[2].host is 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':'','ip_address':''},
>> {'id':3, 'host':'','ip_address':''},
>> {'id':9, 'host':'','ip_address':''}]
>> 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, "")])
>> 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

> 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

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.


More information about the Python-list mailing list