Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare elements of one nested list with another nested list

Tags:

python

list

I got two list of lists

l1 = [[1,2,3],[4,5,6],[7,8,9]]
l2 = [['a','b',4],['c','d',1],['e','f',12],['i','j',18]]

I would like to iterate over l1 and check if l1[0] matches with any l2[2], In this case the output should be [1, l1[0],l2[0]] otherwise output is [0, l1[0], l2[0]]. Output should be a single nested list(or list of tuples) with result for each element of l1. Both lists can have different sizes.

I tried solving this with for-loop like:

output = list()
for i in l1:
   matched = 0
   for j in l2:
       if j[2] == i[0]:
          output.append([1,i[0], j[0]])
          matched = 1
    if matched == 0:
       output.append([0,i[0]])

This give correct output

[[1, 1, 'c'], [1, 4, 'a'], [0, 7]]

However I am looking for a more compact solution. Is it possible to solve this with list comprehension of something similar which can reduce number of lines involved?

I tried a nested list comprehension but couldn't make it work

out = [[(1,i[0],k[0]) if(k[2] == i[0]) else (0,i[0],k[0]) for k in l2] for i in l1]
print(out)
[[(0, 1, 'a'), (1, 1, 'c'), (0, 1, 'e'), (0, 1, 'i')], [(1, 4, 'a'), (0, 4, 'c'), (0, 4, 'e'), (0, 4, 'i')], [(0, 7, 'a'), (0, 7, 'c'), (0, 7, 'e'), (0, 7, 'i')]]
like image 417
Sohaib Farooqi Avatar asked Dec 21 '17 15:12

Sohaib Farooqi


1 Answers

it seems that you're not using all your elements. However, I'd build a dict out of l2 for quick lookup & concision (one-liner would be probably possible, but at the expense of readability & performance)

I'd make that follow with a list comprehension including a ternary to issue 2 or 3 elements depending if the item is found (so no need for a fancy int(if a in l2d) since we can issue 0 or 1 directly). Like this:

l1 = [[1,2,3],[4,5,6],[7,8,9]]
l2 = [['a','b',4],['c','d',1],['e','f',12],['i','j',18]]

l2d = {v[2]:v[0] for v in l2}  # not using v[1]

result = [[1,a,l2d[a]] if a in l2d else [0,a] for a,_,_ in l1]  # using only first element of each l1 triplet...

result:

[[1, 1, 'c'], [1, 4, 'a'], [0, 7]]

(note that carrying other unused items isn't really helping to understand the issue)

like image 56
Jean-François Fabre Avatar answered Sep 30 '22 09:09

Jean-François Fabre