Reputation: 57
Let's say I have a list of lists like
new_list=[[1,2,3],
[9,1,6],
[7,3,4]]
I'd like to do something like
n=new_list.index([7,:,4])
and I'd like
n==2
because indeed,
new_list[2]==[7,3,4]
I hope this example makes my point, I want to find if a list of lists contains a certain list without especifying the full list to be found.
Upvotes: 3
Views: 1313
Reputation: 29417
One can define a partial "match" function where None
matches all and then use next
to find the first partial match (similar to what index
does, finding only the first match):
pMatch = lambda l1, l2: all([x[0] == x[1] or x[0] == None for x in zip(l1, l2)])
# examples of partial matches
pMatch([1, 2, None], [1, 2, 3])
# True
pMatch([1, 2, 4], [1, 2, 3])
# False
new_list = [[1, 2, 3], [9, 1, 6], [7, 3, 4]]
l = [7, None, 4]
next(i for i in range(len(new_list)) if pMatch(l, new_list[i]))
# 2
In one line:
next(i for i in range(len(new_list)) if all([x[0]==x[1] or x[0]==None for x in zip(l, new_list[i])]))
# 2
(assuming that all lists have the same length)
Upvotes: 1
Reputation: 726
This function should do it (quick&dirty):
>>> new_list=[[1,2,3],
... [9,1,6],
... [7,3,4]]
>>>
>>> def find(lst, members):
... for i in range(len(lst)):
... match=True
... for j in members:
... if j not in lst[i]:
... match=False
... break
... if match:
... return i
... return None
...
>>> find(new_list, [2, 3])
0
>>> find(new_list, [3, 1])
0
>>> find(new_list, [2, 4])
>>> find(new_list, [7, 4])
2
>>> find(new_list, [7])
2
>>> find(new_list, [8, 9])
Upvotes: 0
Reputation: 3675
Approach this in two steps:
Define a function that compares a list against a partial list. You can use None
instead of the colon from your example.
def matches(pattern, candidate):
# check that pattern and candidate are lists of same length
# loop over all indices i:
# if pattern[i] is not None, candidate[i] must be equal
Then loop over the list of lists, calling the function from 1. on each element, until you find an item that matches or the list ends.
Upvotes: 0