Return only the first instance of a value found in a for loop

Question:

I have a list of strings that are split in half like the following;

fhlist = [['BzRmmzZHzVBzgVQmZ'],['efmt']]
shlist = [['LPtqqffPqWqJmPLlL', ['abcm']]

The first half is stored in a list fhlist whilst the second in shlist.

So the combined string of fhlist[0] and shlist[0] is BzRmmzZHzVBzgVQmZLPtqqffPqWqJmPLlL.

and fhlist[1] and shlist[1] is efmtabcm

I’ve written some code that iterates through each letter in the first and second half strings, and if any letters appear in both halfs it adds this character to another list found;

found = []
for i in range(len(fhlist)):
    for char in fhlist[i]:
        if char in shlist[i]:
            found.append(char)

However, with the above example, the example list returns me m m m as it is returning every instance of the letter occurring, the letter m occurs 3 times in the combined string BzRmmzZHzVBzgVQmZLPtqqffPqWqJmPLlL I only want to return the code to return m

I previously had;

found = []
for i in range(len(fhlist)):
    for char in fhlist[i]:
        if char in shlist[i] and char not in found:
            found.append(char)

but this essentially ‘blacklisted’ any characters that appeared in other strings, so if another two strings both contained m such as the combined string efmtabcm it would ignore it as this character had already been found.

Thanks for any help!

Asked By: Conor

||

Answers:

You can try this

fhlist = [['BzRmmzZHzVBzgVQmZ'],['efmt']]

shlist = [['LPtqqffPqWqJmPLlL'], ['abcm']]
found = []
for i in range(len(fhlist)):
    for char in ''.join(fhlist[i]):
        for a in ''.join(shlist[i]):
            if a==char and char not in found:
                
                found.append(char)
        
print(found)

Output:

['m']
Answered By: Hiral Talsaniya

IIUC, you are trying to find common characters between each of the respective strings in fhlist and shlist

You can use set.intersection for this after using zip on the 2 lists and iterating on them together with a list comprehension, as follows –

[list(set(f[0]).intersection(s[0])) for f,s in zip(fhlist, shlist)]
[['m'], ['m']]

This works as follows –

1. BzRmmzZHzVBzgVQmZ, LPtqqffPqWqJmPLlL -> Common is `m`
2. efmt, abcm -> Common is `m`
...
till end of list
Answered By: Akshay Sehgal

Expanding my suggestion from the comments since it apparently solves the problem in the desired way:

To dedupe per pairing, you can replace:

found = []
for i in range(len(fhlist)):
    for char in fhlist[i]:
        if char in shlist[i]:
            found.append(char)

with (making some slight idiomatic improvements):

found = []
for fh, sh in zip(fhlist, shlist):  # Pair them up directly, don't operate by index
    found.extend(set(fh).intersection(sh))

or as a possibly too complex listcomp:

found = [x for fh, sh in zip(fhlist, shlist) for x in set(fh).intersection(sh)]

This gets the unique overlapping items from each pairing (with set(fh).intersection(sh)) more efficiently (O(m+n) rather than O(m*n) in terms of the lengths of each string), then you add them all to found in bulk (keeping it as a list to avoid deduping across pairings).

Answered By: ShadowRanger
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.