dic compare

上一篇 / 下一篇  2016-10-18 03:55:26 / 个人分类:tm

a=[{'b':[{'d':'z','e':{'g':'3','f':'2'},'c':'x'},{'d':'y','e':{'g':'3','f':'2'},'c':'x'}],'j':'11','a':'12'},{'b':[{'d':'z','e':{'g':'3','f':'2'},'c':'x'},{'d':'y','e':{'g':'3','f':'2'},'c':'x'}],'j':'21','a':'2'}]

def sortbykeys(dict1):
    return sorted(dict1.items(),key=lambda x:x[0])

# no use, just in case
def sortbyvalues(dict1):
    return sorted(dict1.items(),key=lambda x:x[1])

def sortbyspecifiedkey(list1,key1):
    if len(key1.split('->'))==1:
        return sorted(list1,key=lambda x:x.get(key1))
    elif len(key1.split('->'))==2:
        return sorted(list1,key=lambda x:x.get(key1.split('->')[0]).get(key1.split('->')[1]))
    else:
        return 'Error'
        print("currently only support 2 level, no more!!!!")

def sortlist(list1,key1):
    relist = []
    for x in sortbyspecifiedkey(list1,key1):
        relist.append(sortbykeys(x))
    return relist

# -------------------------------


def getDicspecifiedValue(dict1,list1,index):
    #currently only support 2 level, no more!!!!
    if len(list1[index].split('->'))==1:
        return dict1.get(list1[index])
    elif len(list1[index].split('->'))==2:
        try:
            return dict1.get(list1[index].split('->')[0]).get(list1[index].split('->')[1])
        except:
            for x in dict1:
                if x[0]==list1[index].split('->')[0]:
                    for y in tuple(x[1]):
                        if y[0]==list1[index].split('->')[1]:
                            return y[1]
    else:
        return 'Error'
        print("currently only support 2 level, no more!!!!")

def twodictcompare(dict1,dict2,*specifiedkey):
    countline = 0
    feedlist = []
    fxml = []
    level = 0
    listhappen = 0
    listnum = len(specifiedkey)
    color = {'+':'green','-':'red'}
    def go1(aa,ll,flag,pre=''):
        nonlocal  countline
        flaglist = (',','-,','+,')
        signal = flaglist[flag]
        if isinstance(aa, list):
            nonlocal listhappen
            if listhappen == listnum:
                listhappen = 0
            else:
                listhappen += 1
            feedlist.append('\n'+signal+','*ll+'Group'+str(ll))
            countline += 1
            fxml.append(r'<font color="{}">{}   {} {}<Strong>&lt;{}&gt;</Strong></font>'.format('black','{:<5}'.format(str(countline)),signal[0],'    '*ll,'Group'+str(ll)))

            tmp = list(j1 for j1 in aa if getDicspecifiedValue(j1,specifiedkey,listhappen-1)!='Error')
            for x in tmp:
            # for x in sortlist(aa,specifiedkey[listhappen-1]):
                go1(x,ll,flag)
                fxml.append(r'<br />')
        elif isinstance(aa, dict):
            for x in sortbykeys(aa):
                tmpstr = '\n'+signal+','*ll+x[0]
                if not isinstance(x[1], list) and not isinstance(x[1], dict) and not isinstance(x[1], tuple):
                    go1(x[1],ll,flag,tmpstr)
                else:
                    feedlist.append(tmpstr)
                    countline += 1
                    fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;</font>'.format(color[signal[0]],'{:<5}'.format(str(countline)),signal[0],'    '*ll,x[0]))
                    go1(x[1],ll+1,flag)
        elif isinstance(aa, tuple):
            tmpstr = '\n'+signal+','*ll+aa[0]
            if not isinstance(aa[1], list) and not isinstance(aa[1], dict) and not isinstance(aa[1], tuple):
                go1(aa[1],ll,flag,tmpstr)
            else:
                feedlist.append(tmpstr)
                countline += 1
                fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;</font>'.format(color[signal[0]],'{:<5}'.format(str(countline)),signal[0],'    '*ll,aa[0]))
                go1(aa[1],ll+1,flag)
        else:
            tmpstr = pre+','+str(aa)
            feedlist.append(tmpstr)
            countline += 1
            fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;{}&lt;/{}&gt</font>'.format(color[signal[0]],'{:<5}'.format(str(countline)),signal[0],'    '*ll,pre.split(',')[-1],aa,pre.split(',')[-1]))
        return
    def go(aa,bb,ll,pre=''):
        nonlocal  countline
        if type(aa) != type(bb):
            print("totally different")
            feedlist.append('\n'+"totally different")
            fxml.append(r"totally different")

        else:
            if isinstance(aa, list) and isinstance(bb, list):
                nonlocal listhappen
                if listhappen == listnum:
                    listhappen = 0
                else:
                    listhappen += 1
                feedlist.append('\n'+','*ll+'Group'+str(ll))
                countline += 1
                fxml.append(r'<font color="{}">{}   {} {}<Strong>&lt;{}&gt;</Strong></font>'.format('black','{:<5}'.format(str(countline)),' ','    '*ll,'Group'+str(ll)))

                x1list = sorted([getDicspecifiedValue(x1,specifiedkey,listhappen-1) for x1 in aa])
                x2list = sorted([getDicspecifiedValue(x1,specifiedkey,listhappen-1) for x1 in bb])
                # x1
                x1more = sorted(list(set(x1list)-set(x2list)))
                x2more = sorted(list(set(x2list)-set(x1list)))
                x1andx2 = sorted(list(set(x2list)&set(x1list)))
                x1orx2 = sorted(list(set(x2list)|set(x1list)))

                for key in x1orx2:
                    if key in x1more:
                        tmp = list(j1 for j1 in aa if getDicspecifiedValue(j1,specifiedkey,listhappen-1)==key)
                        listhappen -= 1
                        go1(tmp[0],ll,1) #if isinstance(tmp[0],list) else go1(tmp[0],ll+1,1)
                        fxml.append(r'<br />')
                    elif key in x2more:
                        tmp = list(j1 for j1 in bb if getDicspecifiedValue(j1,specifiedkey,listhappen-1)==key)
                        listhappen -= 1
                        go1(tmp[0],ll,2) #if isinstance(tmp[0],list) else go1(tmp[0],ll+1,2)
                        fxml.append(r'<br />')
                    else:
                        tmp1 = list(j1 for j1 in aa if getDicspecifiedValue(j1,specifiedkey,listhappen-1)==key)
                        tmp2 = list(j1 for j1 in bb if getDicspecifiedValue(j1,specifiedkey,listhappen-1)==key)
                        go(tmp1[0],tmp2[0],ll) #if isinstance(tmp1[0],list) else go(tmp1[0],tmp2[0],ll+1)
                        fxml.append(r'<br />')
            elif isinstance(aa, dict) and isinstance(bb, dict):
                x1more = sorted(list(set(aa.keys())-set(bb.keys())))
                x2more = sorted(list(set(bb.keys())-set(aa.keys())))
                x1andx2 = sorted(list(set(aa.keys())&set(bb.keys())))
                x1orx2 = sorted(list(set(aa.keys())|set(bb.keys())))
                for key in x1orx2:
                    tmpstr1 = '\n'+'-,'+','*ll+key
                    tmpstr2 = '\n'+'+,'+','*ll+key
                    tmpstr3 = '\n'+','+','*ll+key
                    if key in x1more:
                        if not isinstance(aa[key], list) and not isinstance(aa[key], dict) and not isinstance(aa[key], tuple):
                            go1(aa[key],ll,1,tmpstr1)
                        else:
                            feedlist.append(tmpstr1)
                            countline += 1
                            fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;</font>'.format(color['-'],'{:<5}'.format(str(countline)),'-','    '*ll,key))
                            go1(aa[key],ll+1,1)
                    elif key in x2more:
                        if not isinstance(bb[key], list) and not isinstance(bb[key], dict) and not isinstance(bb[key], tuple):
                            go1(bb[key],ll,1,tmpstr2)
                        else:
                            feedlist.append(tmpstr2)
                            countline += 1
                            fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;</font>'.format(color['+'],'{:<5}'.format(str(countline)),'+','    '*ll,key))
                            go1(bb[key],ll+1,2)
                    else:
                        if not isinstance(aa[key], list) and not isinstance(aa[key], dict) and not isinstance(aa[key], tuple) and not isinstance(bb[key], list) and not isinstance(bb[key], dict) and not isinstance(bb[key], tuple):
                            go(aa[key],bb[key],ll,tmpstr3)
                        else:
                            feedlist.append(tmpstr3)
                            countline += 1
                            fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;</font>'.format('gray','{:<5}'.format(str(countline)),' ','    '*ll,key))
                            go(aa[key],bb[key],ll+1)
            elif isinstance(aa, tuple) and isinstance(bb, tuple):
                x1more = sorted(list(set([x[0] for x in aa])-set([x[0] for x in bb])))
                x2more = sorted(list(set([x[0] for x in bb])-set([x[0] for x in aa])))
                x1andx2 = sorted(list(set([x[0] for x in bb])&set([x[0] for x in aa])))
                x1orx2 = sorted(list(set([x[0] for x in bb])|set([x[0] for x in aa])))
                for key in x1orx2:
                    tmpstr1 = '\n'+'-,'+','*ll+key
                    tmpstr2 = '\n'+'+,'+','*ll+key
                    tmpstr3 = '\n'+','+','*ll+key
                    if key in x1more:
                        if not isinstance(dict(aa)[key], list) and not isinstance(dict(aa)[key], dict) and not isinstance(dict(aa)[key], tuple):
                            go1(dict(aa)[key],ll,1,tmpstr1)
                        else:
                            feedlist.append(tmpstr1)
                            countline += 1
                            fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;</font>'.format(color['-'],'{:<5}'.format(str(countline)),'-','    '*ll,key))
                            go1(dict(aa)[key],ll+1,1)
                    elif key in x2more:
                        if not isinstance(dict(bb)[key], list) and not isinstance(dict(bb)[key], dict) and not isinstance(dict(bb)[key], tuple):
                            go1(dict(bb)[key],ll,1,tmpstr2)
                        else:
                            feedlist.append(tmpstr2)
                            countline += 1
                            fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;</font>'.format(color['+'],'{:<5}'.format(str(countline)),'+','    '*ll,key))
                            go1(dict(bb)[key],ll+1,2)
                    else:
                        if not isinstance(dict(aa)[key], list) and not isinstance(dict(aa)[key], dict) and not isinstance(dict(aa)[key], tuple) and not isinstance(dict(bb)[key], list) and not isinstance(dict(bb)[key], dict) and not isinstance(dict(bb)[key], tuple):
                            go(dict(aa)[key],dict(bb)[key],ll,tmpstr3)
                        else:
                            feedlist.append(tmpstr3)
                            countline += 1
                            fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;</font>'.format('gray','{:<5}'.format(str(countline)),' ','    '*ll,key))
                            go(dict(aa)[key],dict(bb)[key],ll+1)
            else:
                if pre[1] not in ['-','+']:
                    if aa==bb:
                         feedlist.append(pre[0]+''+pre[1:]+','+str(aa))
                         countline += 1
                         fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;{}&lt;/{}&gt;</font>'.format('gray','{:<5}'.format(str(countline)),' ','    '*ll,pre.split(',')[-1],str(aa),pre.split(',')[-1]))
                    else:
                        feedlist.append(pre[0]+'-'+pre[1:]+','+str(aa))
                        countline += 1
                        fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;{}&lt;/{}&gt;</font>'.format(color['-'],'{:<5}'.format(str(countline)),'-','    '*ll,pre.split(',')[-1],str(aa),pre.split(',')[-1]))
                        feedlist.append(pre[0]+'+'+pre[1:]+','+str(bb))
                        countline += 1
                        fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;{}&lt;/{}&gt;</font>'.format(color['+'],'{:<5}'.format(str(countline)),'+','    '*ll,pre.split(',')[-1],str(bb),pre.split(',')[-1]))
                else:
                    if aa==bb:
                         feedlist.append(pre+','+str(aa))
                         countline += 1
                         fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;{}&lt;/{}&gt;</font>'.format('gray','{:<5}'.format(str(countline)),' ','    '*ll,pre.split(',')[-1],str(aa),pre.split(',')[-1]))
                    else:
                        feedlist.append(pre+','+str(aa))
                        countline += 1
                        fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;{}&lt;/{}&gt;</font>'.format('gray','{:<5}'.format(str(countline)),' ','    '*ll,pre.split(',')[-1],str(aa),pre.split(',')[-1]))
                        feedlist.append(pre+','+str(bb))
                        countline += 1
                        fxml.append(r'<font color="{}">{}   {} {}&lt;{}&gt;{}&lt;/{}&gt;</font>'.format('gray','{:<5}'.format(str(countline)),' ','    '*ll,pre.split(',')[-1],str(bb),pre.split(',')[-1]))
        return
    go(dict1,dict2,level)
    feedlist[0] = feedlist[0][1:]
    tfxml = []
    for x in fxml:
        tfxml.append(x+'\n')
    return feedlist,tfxml

opofile = r'.\c2.txt'
flo = open( opofile,'w')
flo.write(str(Ufo_1))
flo.close()
opofile = r'.\c3.txt'
flo = open( opofile,'w')
flo.write(str(Ufo_2))
flo.close()
Ufo_2 = []
# ddd=twodictcompare(a,b,'ExtensionDFID','ExDate->Date')[0]
# ccc=twodictcompare(a,b,'ExtensionDFID','ExDate->Date')[1]
ccc = twodictcompare(a,b,'ExtensionDFID','ExDate->Date')[1]

with open('1.csv','w') as f1:
    f1.writelines(ccc)


with open('1xml.html','w') as f1:
    ccc.insert(0,'<pre>\n')
    ccc.insert(0,'<body bgcolor="#FFFFFF">\n')
    ccc.insert(0,'<html><head><title>XML diff</title></head>\n')
    ccc.append('</pre></body></html>\n')

    f1.writelines(ccc)

相关阅读:

TAG: compare

 

评分:0

我来说两句

Open Toolbar