简体   繁体   中英

How to compare two lists to keep matching substrings and also how to retain the order based on substring?

There is a similar question, posted in other thread, but I would like to have a different output How to compare two lists to keep matching substrings?

And List A doesn't have a consistent pattern

A = ['dataFile1999', 'dataFile::2000', 'Resultx2001', 'Filter2002']
B = ['2000', '1999', '1998', '2005', '2002','2005']

C = [x for x in A if any(b in x for b in B)]

print(C)

Output:

['dataFile::2000', 'dataFile1999','Filter2002']

But I would like to have the output in the same order as the substring list B also, if there is any string missing - it should still keep the string in the list.

['dataFile::2000','dataFile1999','1998','2005','Filter2002','2005']

A complicated one-liner, just for the fun;) No assumption on the pattern.

[filter(lambda a : b in a, A).__next__() if any(b in a for a in A) else b for b in B]

['dataFile2000', 'dataFile1999', '1998', '2005', 'dataFile2002', '2005']

or without filter

[[a for a in A if b in a][0] if any(b in a for a in A) else b for b in B]

['dataFile2000', 'dataFile1999', '1998', '2005', 'dataFile2002', '2005']

This would be an equivalent expanded code:

l=list()
for b in B:
    if any(b in a for a in A):
        for a in A:
            if b in a:
                l.append(a)
    else:
        l.append(b)
        
print(l)

and this a more efficient version:

l=list()
for b in B:
    this_element = b
    for a in A:
        if b in a:
            this_element = a
            break
    l.append(this_element)

print(l)

As your list A has a consistent pattern, these should work well:

C = ['dataFile'+b if 'dataFile'+b in A  else b for b in B]

Output:

>>> C
['dataFile2000', 'dataFile1999', '1998', '2005', 'dataFile2002', '2005']

OR

C = ['dataFile'+b if b in ''.join(A)  else b for b in B]

Output:

>>> C
['dataFile2000', 'dataFile1999', '1998', '2005', 'dataFile2002', '2005']

EDIT

As OP mentioned that list A can be in consistent in its prefix so:

C = [i[0] for i in [[a for a in A if b in a] or [b] for b in B]]

Output:

['dataFile2000', 'dataFile1999', '1998', '2005', 'dataFile2002', '2005']

Maybe add another list comprehension that gets all items of B which are not in C and then add the results to the other list

    D = [x for x in B if not any(x in c for c in C)]
    result = C.extend(D)

You could create a copy of C and replace its values by matching values from A elsewise keep the original value from C :

A = ['dataFile1999', 'dataFile::2000', 'Resultx2001', 'Filter2002']
B = ['2000', '1999', '1998', '2005', '2002', '2005']
C = B[:] # copy of B

for i, y in enumerate(B):
    _value = y  # Use as default if not matching value found!
    for f in A:
        if f.endswith(y):
            C[i] = f
            break
print(C)

Out:

['dataFile::2000', 'dataFile1999', '1998', '2005', 'Filter2002', '2005']

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