Reputation: 3882
I have a 2D list of lists, I am doing some stuff to it and getting, as a result a slightly modified 2d lists of lists. I cannot track what changes are being made until after I get the new list back. I want to get a list of all the items that have been changed such that
[[1,2,3], [4,5,6], [7,8,9]]
becomes [[1,None,3], [4,None,6], [7,None, None]]
and I would get a list [(0,1), (1,1), (2, 1), (2,2)]
I know you can normally do list(set(a)-set(b))
but when I tried it I got TypeError: unhashable type: 'list'
So what is the most efficient way of doing this?
Upvotes: 2
Views: 1723
Reputation: 8668
If the lists have a regular structure, that is each of the sub-lists has the same length, and you don't mind using external packages, numpy
can help.
import numpy as np
a = np.array([[1,2,3], [4,5,6], [7,8,9]])
b = np.array([[1,None,3], [4,None,6], [7,None, None]])
print(np.where(a!=b))
>>>(array([0, 1, 2, 2]), array([1, 1, 1, 2]))
Upvotes: 0
Reputation: 251096
Using zip
, enumerate
and a generator function:
def diff(lis1, lis2):
for i, (x, y) in enumerate(zip(lis1, lis2)):
for j, (x1, y1) in enumerate(zip(x, y)):
if x1 != y1:
yield i, j
...
>>> lis1 = [[1,2,3], [4,5,6], [7,8,9]]
>>> lis2 = [[1,None,3], [4,None,6], [7,None, None]]
>>> list(diff(lis1, lis2))
[(0, 1), (1, 1), (2, 1), (2, 2)]
Upvotes: 4
Reputation: 369314
Using list comprehension:
>>> a = [[1,2,3], [4,5,6], [7,8,9]]
>>> b = [[1,None,3], [4,None,6], [7,None, None]]
>>> [(i,j) for i, row in enumerate(a) for j, x in enumerate(row) if b[i][j] != x]
[(0, 1), (1, 1), (2, 1), (2, 2)]
Upvotes: 3