List Filtering on Multiple Parameters

This is not a question or issue, I just simply wanted to share what I’ve done and see if there are any issues with my logic or improvements that could be made.

I found that filtering a category, such as doors, based on multiple parameters is a pain. Not only does Contain not always work (due to issues I couldn’t spend time identifying) and I need a custom sort, I also need multiple filters if I want to filter based on two or more parameters, say both Phase Created and Comments. Further still, even after filtering, vanilla and most other methods I’ve seen generate a boolean list that needs to be parsed or used to generate a mask or index list before finally being able to cull the list.

My solution: I created a python script that allows for multiple parameter inputs (not universally applicable; filters exact matches, so filtering based on substrings still require a separate node) and outputs “in” and “out” lists of the index values of the original list that fall within or without (respectively) of the list of filter values. From this, simply plug the desired index list into the List.RemoveItemAtIndex node and you’re done. Further functionality could be implemented to allow option for substring searching and case sensitivity for either string/string or string/substring matching, but as it stands, I prefer this node to any other method I’ve seen. Simpler to plug and play, and any filtering done for non-culling applications can more easily be parsed from the index lists into a boolean pattern. Much like the vanilla Contains node, it breaks down at three tier and above lists (4+ Levels), and by default it performs the cross product lacing option of Contains.

Filter input from a Code Block can be in the form of either “a”; or {“a”};, my script with automatically wrap any non list input into a list for looping. Obj list input must be a one or two tier list, though I find it doubtful you would ever perform this type of filter on anything but a list.

Custom Node Setup:
image

Code:
lst1 = []
lst2 = []
inpt = []

if type(IN[0][0]) is list:
	inpt = IN[0]
else:
	inpt.append(IN[0])

for f in IN[1] if type(IN[1]) is list else {IN[1]}:
	for t in inpt:
		for i, s in enumerate(t):
			if f == s:
				if i not in lst1:
					lst1.append(i)
			if i not in lst2:
				lst2.append(i)

for l in lst1:
	lst2.remove(l)

OUT = [lst1, lst2]
2 Likes