0

I'm looking for a better and simpler solution to find changes between two nested lists within dicts, archived and actual data.

I want to find:

  • added data in actual data

  • deleted data from actual data

  • changes inside data -search by id values (unique number for data)

self.l_dicts_arch - archived data

self.l_dicts_actual - actual data

Here's my function:

def check(self):
    for item in self.l_dicts_arch: 
        if item in self.l_dicts_actual:#remove correct data
            self.l_dicts_actual.remove(item) 
        elif item not in l_dicts_actual:
            for item2 in l_dicts_actual:
                if item['id']==item2['id']:#display and remove data with error
                    print 'Found error in data'
                    print 'from first list', item
                    print 'from second list',item2
                    actual_list.remove(item2)
                else:
                    print 'This item was removed from actual list'#display deleted data
                    print item
    if len(self.l_dicts_actual)!=0:
        print 'This item was added on actual list'
        for item in self.l_dicts_actual:
            print item
Arundas R
  • 770
  • 7
  • 20
MartinP
  • 527
  • 5
  • 17

1 Answers1

1

For the following sets :

actual = [{'id' : 4, 'data' : 'foo'}, {'id' : 5, 'data' : 'toto'}, {'id' : 7, 'data' : 'tagada'}] arch = [{'id' : 4, 'data' : 'foo'}, {'id' : 5, 'data' : 'toto2'}, {'id' : 6, 'data' : 'tata'}]

Here are some solutions :

  • Items deleted (finding on 'id' tag) :

deleted = filter(lambda x: not x['id'] in map(lambda x: x['id'], actual), arch)

  • Added data (finding on 'id' tag) :

added = filter(lambda x: not x['id'] in map(lambda x: x['id'], arch), actual)

  • Modified items :

modified = filter(lambda x: not x in arch, filter(lambda x: x['id'] in map(lambda x: x['id'], arch), actual))

A cool code could be something like this :

def check(arch, actual): id_actual = map(lambda x: x['id'], actual) id_arch = map(lambda x: x['id'], arch) deleted = filter(lambda x: not x['id'] in id_actual, arch) added = filter(lambda x: not x['id'] in id_arch, actual) modified = filter(lambda x: not x in arch, filter(lambda x: x['id'] in id_arch, actual))

EDIT: I think you can optimize that, I'm looking for another solution...

FunkySayu
  • 7,641
  • 10
  • 38
  • 61
  • Thanks Guy, your solution really help me now, but if you find some better, paste here :-) – MartinP Oct 02 '14 at 09:05
  • I think that you can patch something in this code : if you know that few elements of your list will be modified, you can add at the top of check function something like this : `actual, arch = filter(lambda x: x not in arch, actual), filter(lambda x: x not in actual, arch)` That will reduce a lot of treatments. I'm looking for something else too. – FunkySayu Oct 02 '14 at 09:10
  • I'm also a fanboy of `filter`, `map` and `lambda`, but you also can do it with easier list declaration i think... – FunkySayu Oct 02 '14 at 09:12