Python - How to partial match elements in listA to rows in listB

Viewed 56

I have 2 lists, one with jobs and one with data.

jobs = [
  'P01_TEST1_C', 
  'P01_TEST3_B', 
  'P01_TEST5_F', 
  'P01_QUALITY_C'
]

data = [
  ['JOB','X01_TEST1_C', 'NAME', 'DATE', 'EXTRADATA'],
  ['JOB','P01_TEST3_C', 'NAME', 'DATE', 'EXTRADATA'],
  ['JOB','X01_TEST1002_C', 'NAME', 'DATE', 'EXTRADATA'],
  ['JOB','X01_TEST4231_C', 'NAME', 'DATE', 'EXTRAP01_TEST5_FDATA']
]

I want to find the lines in data that have jobs. The first 3 characters in jobs don't matter so

answer I want would be =

['JOB','X01_TEST1_C', 'NAME', 'DATE', 'EXTRADATA'] #matching on P01_TEST1_C

['JOB','P01_TEST3_B', 'NAME', 'DATE', 'EXTRADATA'] # matching on P01_TEST3_B

['JOB','X01_TEST4231_C', 'NAME', 'DATE', 'EXTRAP01_TEST5_FDATA']] #matching on the P01_TEST5_F in between the EXTRADATA

If I use the below it matches if I make it exact but wouldn't find the name within the EXTRADATA

jobs = ['X01_TEST1_C','P01_TEST3_B C']

newest = [s for s in rows if any(rows in s for rows in jobs)]

but what I think I want to do is search data for ['_TEST1_C', '_TEST3_B', '_TEST5_F', '_QUALITY_C'] but with * wildcards

( I have removed the front part with

for i in jobs:
    i = i[3:]

)

Any help greatly appreciated Thanks

2 Answers

The slice approach that you initiated works if you followed it through to the jobs list with an additional nested for loop. You can then compare the slices j[3:] == k[3:] which represent data[3:] == jobs[3:].

there were a few undefined variables so i just assigned them values for the purpose of the question:

NAME='hello'
DATE = '1 jan 2000'
EXTRADATA = 'world'
EXTRAP01_TEST5_FDATA = ''

An now here is the solution:

jobs = ['P01_TEST1_C', 'P01_TEST3_B', 'P01_TEST5_F', 'P01_QUALITY_C']
data = [['JOB','X01_TEST1_C', NAME, DATE, EXTRADATA],['JOB','P01_TEST3_C', NAME, DATE, EXTRADATA],['JOB','X01_TEST1002_C', NAME, DATE, EXTRADATA],['JOB','X01_TEST4231_C', NAME, DATE, EXTRAP01_TEST5_FDATA]]

for i in data:
    for j in i:
        s = j[3:]
        for k in jobs:
            if j[3:] == k[3:]:
                print('found', j[3:])

which returns:

found _TEST1_C

You can check if a substring of each entry's "job" is "in" jobs if we limit each of those to the corresponding substring. A generator expression will give us the substrings of the entries in jobs.

[d for d in data 
   if d[1][3:] in (j[3:] for j in jobs)]

If you don't want to generate the "wildcards" on each iteration:

wildcards = [j[3:] for j in jobs]

[d for d in data if d[0][3:] in wildcards]
Related