Check element in list of lists from items in another list of lists

Viewed 172

I have one list of lists list1 and one list to check list2 that I'd like to run a for loop to check if elements from list2 are in list1, then append the element present to 'models' which is a list that pulls the first index from each list in list1.

No errors but I believe it might be because of the types I'm working with.

My code:

a = "sample.txt"  # Contains multiple rows like "model1//h//4385////ffm1//gg5////lmm"

file1 = open(a, "r")
with open(a, 'r') as file:
    lines = [line.rstrip('\n') for line in file]

cleaned_data = []
def split_lines(lines, delimiter, remove='^[0-9.]+$'):
    for line in lines:
        tokens = line.split(delimiter)
        tokens = [re.sub(remove, "", token) for token in tokens]
        clean_list = list(filter(lambda e: e.strip(), tokens))
        cleaned_data.append(clean_list)

split_lines(lines, "/")
print(cleaned_data)
# outputs: ["model1", "h", "ffm1", "gg5", "1mm"] for each line in txt

##cleaned_data = [["model1", "h", "ffm1", "gg5", "1mm"], then more of this
## in a list of lists

list2 = ['gg5', 'pp6', 'gg7']  # to check element in the cleaned_data

models = []
for item in cleaned_data:
    if item[0] not in models:
        models.append(item[0])
##  models = ['model1', 'model2', 'model3']

for item in cleaned_data:
    if item == insulation:
        models.append(item)
print(models)

#This is where I want to check if elements in list2 are in the list of lists #in cleaned_data, then append that elements from list2 to index1 of models.

Output:

['model1', 'model2', 'model3']

Expected output:

[['model1', 'gg5'], ['model2', 'pp6'], ['model3', 'gg5']
4 Answers

There are some issues with your code.

Your loop doesn't do anything, because when you do:

if item == list2:

The comparison will always be false, as the structure of item and list2 are different (e.g. you're comparing ["model1", "yes", "TT42"] with ['TT42', 'GG50', 'BB12']).

Your output is ['model1', model2', 'model3'] but it is because you defined it as such, the loop didn't change it.

Also, when you do:

models.append(item)

You were going to add a whole list inside the models variable. For instance, if the first comparison of the loop was correct, you'd have:

>>> print(models)
['model1', model2', 'model3', ['model1', 'yes', 'TT42']]

And it's obviously not what you want.


Here's a way of doing what you want:

list1 = [['model1', 'yes', 'TT42'], 
        ['model2', 'yes', 'GG50'],
        ['model3', 'no', 'BB12']]

list2 = ['TT42', 'GG50', 'BB12']
models = [[item[0], item[2]] for item in list1 if item[2] in list2]

Output:

>>> print(models)
[['model1', 'TT42'], ['model2', 'GG50'], ['model3', 'BB12']]

IIUC this will take your list 2 and compare it to your list 1 and find where all anything from list2 is equal to anything from list1 and add it to the models list

list1 = [['model1', 'yes', 'TT42'], 
        ['model2', 'yes', 'GG50'],
        ['model3', 'no', 'BB12']]

list2 = ['TT42', 'GG50', 'BB12']

single_list = [list1[x][y] for x in range(0, len(list1)) for y in range(0, len(list1[x]))]

models = [x for x in list2 for y in single_list if x ==y]
models

If this is not the expected results please provide more details and expected results.

I'm not sure if I understand correctly, but does this produce what you want?:

list1 = [["model1", "h", "ffm1", "gg5", "1mm"], 
    ["model2", "h", "ffm1", "pp6", "1mm"],
    ["model2", "h", "ffm1", "gg7", "1mm"]]

list2 = ['gg5', 'pp6', 'gg7']
models=[]

for x in list2:
    for y in list1:
        if x in y[1:]:
            models.append([y[0],x])
    

Also, this is another way I could think of:

cleaned_data = [["model1", "h", "ffm1", "gg5", "1mm"], 
    ["model2", "h", "ffm1", "pp6", "1mm"],
    ["model2", "h", "ffm1", "gg7", "1mm"]]

list2 = ['gg5', 'pp6', 'gg7']
models = {}
for item in cleaned_data:
    if item[0] not in models:
        models[item[0]]=[] 
for x in list2:
    for y in list1:
        if x in y[1:]:
            models[y[0]].append(x)

result=[[item[0],*item[1]] for item in models.items()]

# result: [['model1', 'gg5'], ['model2', 'pp6', 'gg7']]

For each row, you can extract the first column as the model name and the rest as properties, and obtain the property that matches any item in list2 by performing a set intersection with list2, which, for efficiency, should be converted to a set in advance:

set2 = set(list2)
models = [[model, prop] for model, *props in list1 for prop in set2.intersection(props)]

Demo: https://replit.com/@blhsing/FakeFaintVendors

Related