简体   繁体   中英

Finding a not exact match in a list of lists

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.

Approach this in two steps:

  1. 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 
  2. 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.

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])

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM