Python. Filter out items of sublists that do not contain list of strings but all string list items are contained in those sublists

Hello,

I am trying to filter out (remove, purge from original list) items of sublists which are not the items that are contained in a list of strings as input, so if any sublist contains those input strings, remove only the items of that sublist that do not contain the string list, and leave at it is the rest of sublist that do not have ALL the string list items requested.

I am trying this in python:

  1. find if a list of sublists contain a list of strings within each sublist, so get true or false for each item.

  2. if it is contained give me true for the entire sublist that contains the strings, if not, give me false.

  3. if the sublist did not contain the list of strings, make the boolean result of step 1 as True for those items of the sublists that did not contain the strings. In Dynamo core nodes what I would do is to ask if All items of sublist are False, so if it is true all are false, make all items of those sublists as True and leave the other sublists as they are. NEED HELP :upside_down_face:

  4. Filter the true values, get rid of the False values.

For example:

OriginalList=[1,2,3,4,5],[0,1,1,3,6],[0,2,3],[2,4,5],[Empty List]
SearchListStrings=[1,3]

Result wanted step 1=[true,false,true,false,false],[false,true,true,true,false],[false,false,true],[false,false,false],[false]
Result wanted step 2=[true],[true],[false],[false],[false]
Result wanted step 3=[true,false,true,false,false],[false,true,true,true,false],[true,true,true],[true,true,true],[true]
Result wanted step 4= [1,3],[1,1,3],[3],[2,4,5],[Empty List]

With Dynamo OOTB nodes it is resolved like this:


FILTEROUT.dyn (23.2 KB)

@ruben.romero

thats horrible :slight_smile:

but Step1 works… i need list.comprehensions

import sys
import clr

l1 = IN[1][0]
l2 = IN[1][1]

l3 = IN[0][0]
l4 = IN[0][1]
l5 = IN[0][2]
l6 = IN[0][3]


s =[]
r = []
o = []
p = []

lists = s,r,o,p

output = lists

for i in l3:
	if i == l1:
		s.append(True)
	elif i == l2:
		s.append(True)
	else:
		s.append(False)

for x in l4:
	if x == l1:
		r.append(True)
	elif x == l2:
		r.append(True)
	else:
		r.append(False)

for z in l5:
	if z == l1:
		o.append(True)
	elif z == l2:
		o.append(True)
	else:
		o.append(False)

for c in l6:
	if c == l1:
		p.append(True)
	elif c == l2:
		p.append(True)
	elif len(l6) == 0:
		p.append(False)
	else:
		p.append(False)
		
if len(l6) == 0:
	p.append(False)
		
OUT = output


Step 4:

# Phython-Standard- und DesignScript-Bibliotheken laden
import sys
import clr

l1 = IN[1][0]
l2 = IN[1][1]

l3 = IN[0][0]
l4 = IN[0][1]
l5 = IN[0][2]
l6 = IN[0][3]


s = []
r = []
o = []
p = []

lists = s,r,o,p

output = lists

for i in l3:
	if i == l1:
		s.append(i)
	elif i == l2:
		s.append(i)
	else:
		s.Remove(i)

for x in l4:
	if x == l1:
		r.append(x)
	elif x == l2:
		r.append(x)
	else:
		r.Remove(x)


for z in l5:
	if z == l1:
		o.Remove(z)
	elif z == l2:
		o.Remove(z)	
	else:
		o.append(z)

for c in l6:
	if c == l2:
		p.append(c)
	elif c == l1:
		p.append(c)
	else:
		p.remove(c)
		
if len(l6) == 0:
	p.append("Empty List")
		
OUT = output



original = IN[0]
search = IN[1]

output = []
for sub in original:
	new = [s for s in sub if s in search]
	if new: output.append(new)
	else: output.append(sub)

OUT = output

The steps you’ve outlined do almost the same. I just left out the booleans. You don’t need a “masking list” with true/false in most cases. Once you check if a value fulfills the conditions, you can process it immediatly.

A bit of explaination:

  • new = [s for s in sub if s in search]
    → create a new list only containing elements that are in search list
  • if new: output.append(new)
    → new has values and goes into output
  • else: output.append(sub)
    → new is empty and original sublist goes into output

2 Likes

hello @Kibar it is great and easy. I tried it but not sure if the search input list searches if the items are contained inside the items of the original list either as part of the items, so what happens if this example is made with strings and want to search if “post” is contained in “postman” original string list.

Because I do not know how to achieve that conditions of containing string in part of the strings, I created a bool list that checks if the string is contained but if I apply this code for true or false, I do not get the result wanted because the input list is composed by items that must appear all of them within any original sublist.

something like that:

def ListContains(item, filter):
	bool = False
	for i in filter:
		if i in item:
			return True
			bool = True
	if not bool:
		return False 

def ProcessListArg(_func, _list, _arg):
	return map( lambda x: ProcessListArg(_func, x, _arg) if type(x)==list else _func(x, _arg), _list )

xxx = ProcessListArg(ListContains, originalList, searchList))