mbs
mbs

Reputation: 421

Match lists and write result to new list

I have a problem matching lists in python.

list1 = [["id1","string1","string2"],["id2","string3","string4"]]
list2 =   [["id1","string1","string2", "string3"],["id3","string4","string5", "string6"]]

I want something like this

list3 = [["id1", "string1", "string2", "string3"],["id2","string3","string4"],["id3","string4","string5", "string6"]]

if an id from list1 is in list2 then write the element from list2 (e.g. ["id1","string1","string2"]) to a new list. If it's not in the list take the element from list1 and write it to the new list. At the end the result should look something like this

I tried it this way

for p in list1:
   for d in list2:
       if ( (p[0] in list2)):
          list3.append(d)
          next
       else:
          list3.append(p)

Upvotes: 1

Views: 79

Answers (2)

thefourtheye
thefourtheye

Reputation: 239443

If the order doesn't matter then the best way is to convert them to dictionaries and match them like this

dict1 = {item[0]: item for item in list1}
dict2 = {item[0]: item for item in list2}
print [dict2.get(item, dict1.get(item)) for item in dict1.viewkeys() | dict2]

Output

[['id2', 'string3', 'string4'],
 ['id3', 'string4', 'string5', 'string6'],
 ['id1', 'string1', 'string2', 'string3']]

If you are using Python 3.x, then use dict.keys instead of dict.viewkeys, like this

print([dict2.get(item, dict1.get(item)) for item in dict1.keys() | dict2])

The same can be written like this

[dict2.get(item) or dict1.get(item) for item in dict1.keys() | dict2]

Upvotes: 2

zhangxaochen
zhangxaochen

Reputation: 34007

It's better to transform your lists to dicts, which is easier to do the job, e.g.:

In [259]: list1 = [["id1","string1","string2"],["id2","string3","string4"]]

In [260]: {i[0]:i[1:] for i in list1}
Out[260]: {'id1': ['string1', 'string2'], 'id2': ['string3', 'string4']}

then you can check if the keys (namely your ids) in the 1st dict are in the 2nd dict:

In [270]: d1 = {i[0]:i[1:] for i in list1}

In [271]: d2 = {i[0]:i[1:] for i in list2}

In [272]: d1.update(d2)

In [273]: d1
Out[273]: 
{'id1': ['string1', 'string2', 'string3'],
 'id2': ['string3', 'string4'],
 'id3': ['string4', 'string5', 'string6']}

If you want to convert it back to list anyway:

In [275]: [[k]+d1[k] for k in d1]
Out[275]: 
[['id2', 'string3', 'string4'],
 ['id3', 'string4', 'string5', 'string6'],
 ['id1', 'string1', 'string2', 'string3']]

Upvotes: 2

Related Questions