Mathew Freu
Mathew Freu

Reputation: 21

How to compare two nested lists?

I have two nested lists. Both lists are quite similar, they are different versions of the same file written on top of each other.

The list structure looks like list = [[name, version, id],[name, version, id], ...]

list_1 = [
['mipl-abnd','v1.0.2','eelp234'],
['mipl-avfd','v1.1.5','32fv423'],
['mipl-awsd','v9.0.2','234eelp'],
['mipl-tgfd','v3.0.0','124fdge'],
['mipl-hrdss','v1.0.2','543rfd3'],
['mipl-oldss','v1.0.2','eelp234']] 

list_2 = [
['mipl-abnd','v1.0.2','eelp234'],
['mipl-avfd','v1.1.6','3254323'],
['mipl-awsd','v9.0.2','234eelp'],
['mipl-tgfd','v3.0.0','124fdge'],
['mipl-hrdss','v1.0.2','543rfd3'],
['mipl-newss','v1.0.2','eelp234']] 

I want to iterate and compare if the names in list_1 exist in the list_2, and if it does, if the version of that component in list_1 is not equal to version of the component in list_2 (if there is a version upgrade of a library), then print the newlist_1 = [name, old version, new version, old id, new id] for all unique cases.

If there is a name in list_1, which does not exist in list_2, meaning a library is deprecated, in that case, a new output list should contain newlist_2 = [name, old version, 'deprecated', old id, 'deprecated'].

If there is a name in list_2, which does not exist in list_1, meaning a library is newly added, in that case, a new output list should contain newlist_3 = [name, 'new', new version, new, new id].

The final output should be 3 lists and should get:

newlist_1 = ['mipl-avfd', 'v1.1.5', 'v1.1.6','32fv423', '3254323']
newlist_2 = ['mipl-oldss','v1.0.2', 'deprecated','eelp234', 'deprecated']
newlist_3 = ['mipl-newss', 'new','v1.0.2','new', 'eelp234']

I tried to write something like:

for items in list_1:
    for item in list_2: 
        if item[0] == items[0] and item[1] != items[1]:
             list_difference = [item[0], items[1], item[1], items[2], items[2]]
             newlist_1.append(list_difference)
        elif item[0] not in items[0]: 
             list_old_param = [item[0], item[1], 'deprecated', items[2], 'not-exist']
             newlist_2.append(list_old_param)
        elif items[0] not in item[0]:
             list_new_param = [item[0], 'new' , items[1], 'new', items[2]]
             newlist_3.append(list_new_param)
 

All data seems to append and create multiple entries because of the two for loops, so how do I comprehend lists?

Questions : How to make it work with appending only unique entries? What are some smart ways to write code to compare such two lists? What are the simplest ways? how to ensure the loops do not overfit these lists as the lists would keep on changing?

Upvotes: 2

Views: 269

Answers (1)

quamrana
quamrana

Reputation: 39354

Another way to do this is to run through each list in turn looking for names in the other list. You can get direct access by using two dicts.

My function below prepares the data by converting the lists to dicts and running through each dict and attempting to access the name in the other.

list_1 = [
['mipl-abnd','v1.0.2','eelp234'],
['mipl-avfd','v1.1.5','32fv423'],
['mipl-awsd','v9.0.2','234eelp'],
['mipl-tgfd','v3.0.0','124fdge'],
['mipl-hrdss','v1.0.2','543rfd3'],
['mipl-oldss','v1.0.2','eelp234']] 


list_2 = [
['mipl-abnd','v1.0.2','eelp234'],
['mipl-avfd','v1.1.6','3254323'],
['mipl-awsd','v9.0.2','234eelp'],
['mipl-tgfd','v3.0.0','124fdge'],
['mipl-hrdss','v1.0.2','543rfd3'],
['mipl-newss','v1.0.2','eelp234']]

def compareLists(l1, l2):
    d1 = {k:[v1,v2] for k,v1,v2 in l1}
    d2 = {k:[v1,v2] for k,v1,v2 in l2}
    result = []
    for k,v in d2.items():
        if k in d1:
            v1 = d1[k]
            if v1[0] != v[0]:
                result.append([k,v1[0],v[0], v1[1],v[1]])
        else:
            result.append([k,'new',v[0],'new', v[1]])

    for k,v in d1.items():
        if k not in d2:
            result.append([k,v[0],'deprecated', v[1], 'deprecated'])
    
    return result

r = compareLists(list_1,list_2)
for d in r:
    print(d)

Output as required.

Upvotes: 1

Related Questions