Replace list of list with “condensed” list of list while maintaining order

前端 未结 7 1523

I have a list of list as in the code I attached. I want to link each sub list if there are any common values. I then want to replace the list of list with a condensed list

7条回答
  •  南方客
    南方客 (楼主)
    2020-11-30 08:22

    This solution uses only an Ordered Dictionary.
    deepcopy() is necessary if one wants the original copy to remain unchanged.

    from collections import OrderedDict
    from copy import deepcopy
    
    def treat(passed_list):
        L = deepcopy(passed_list)
    
        dic = OrderedDict()
        for subl in L:
            for x in subl:
                if x not in dic:
                    dic[x] =  subl
        print 'dic at start'
        print '\n'.join('%-3s : %s' % (a,dic[a])
                        for a in dic) + '\n'
    
        for sublist in L:
            short = []
            short.extend(el for el in sublist
                         if el not in short)
            seen  = []
            for k,val in dic.iteritems():
                if val is sublist:
                    break
                if k in short:
                    if val not in seen:
                        seen.append(val)
    
            sumseen = []
            for elseen in seen:
                for y in elseen:
                    sumseen.append(y)
                    dic[y] = sumseen
    
            if seen:
                for el in sublist:
                    if el not in sumseen:
                        sumseen.append(el)
                        dic[el] = sumseen
    
            sublist[:] = short
    
        cumul = []
        cumul.extend(lu for lu in dic.itervalues()
                     if lu not in cumul)
        return cumul
    
    
    plus = [[1,2,3,2,1],[10,5,5,5,10],
            [8,5,3,3,5],[45,50,12,45,40,12]]
    
    lst = [[1,2,3], [10,5], [3,8,5]]
    
    for one_list in (plus,lst):
        print 'one_list before == %r\n' % one_list
        print 'treat(one_list) == %r\n' % treat(one_list)
        print 'one_list after  == %r\n' % one_list
        print '===================================='
    

    result

    one_list before == [[1, 2, 3, 2, 1], [10, 5, 5, 5, 10], [8, 5, 3, 3, 5], [45, 50, 12, 45, 40, 12]]
    
    dic at start
    1   : [1, 2, 3, 2, 1]
    2   : [1, 2, 3, 2, 1]
    3   : [1, 2, 3, 2, 1]
    10  : [10, 5, 5, 5, 10]
    5   : [10, 5, 5, 5, 10]
    8   : [8, 5, 3, 3, 5]
    45  : [45, 50, 12, 45, 40, 12]
    50  : [45, 50, 12, 45, 40, 12]
    12  : [45, 50, 12, 45, 40, 12]
    40  : [45, 50, 12, 45, 40, 12]
    
    treat(one_list) == [[1, 2, 3, 10, 5, 8], [45, 50, 12, 40]]
    
    one_list after  == [[1, 2, 3, 2, 1], [10, 5, 5, 5, 10], [8, 5, 3, 3, 5], [45, 50, 12, 45, 40, 12]]
    
    ====================================
    one_list before == [[1, 2, 3], [10, 5], [3, 8, 5]]
    
    dic at start
    1   : [1, 2, 3]
    2   : [1, 2, 3]
    3   : [1, 2, 3]
    10  : [10, 5]
    5   : [10, 5]
    8   : [3, 8, 5]
    
    treat(one_list) == [[1, 2, 3, 10, 5, 8]]
    
    one_list after  == [[1, 2, 3], [10, 5], [3, 8, 5]]
    
    ====================================
    

    This solution has an inconvenience: it is 2 to 3 times slower than the J.F. Sebastian's solution.

提交回复
热议问题