Elegantly group elements in three sublists based on comparison

Hi all,

I would like to group my elements in three lists based on whether the distance is within, between or above the two margins given. I have the following code now which works but I don’t really like the boolmask filters and feel like there is a better solution but I haven’t been able to achieve it, also not in python because I am unable to get it to work due to the sublists.


Forum.dyn (15.3 KB)

Combine your conditions into nested If statements that return 3 unique values based on the condition they meet. Then use GroupByKey to group the items based on the unique value.

That being said, Python would be way better. Why are the sublists a problem exactly?

Perhaps something like this?

keys = dists < low? 1 dists < high? 2 : 3;
List.GroupByKey(elems, keys)[“groups”];

You could also use a sorted lists of values and get the first index of ‘false’ on a less than test and use that as a keys.

Hi @Nick_Boyts , @jacob.small ,

Thanks for your input!! Didn’t think about using GroupByKey here.
Regarding the Python: I couldn’t get it to work yesterday, it was late and I was tired, but today with a new, fresh look i’ve got working code :star_struck: !

I’ve done some testing with three methods: 1. List.GroupByKey, 2. List.FilterByBoolMask and 3. Python script. Using the TuneUp method I’ve determined that the Python script is the fastest method.

  1. Code Block (630ms) + GroupByKey (115ms)
  2. Code Block (1225ms) + List.BoolmaskFilters (120, 128 & 193 ms)
  3. Python (320ms)

Python Code
elements = IN[0]
distances = IN[1]
inner_margin = IN[2]
outer_margin = IN[3]

def group_elements_by_distance(elements, distances, inner_margin, outer_margin):
    within_margin = []
    between_margin = []
    above_margin = []

    for element_group, distance_group in zip(elements, distances):
        within_margin_group = []
        between_margin_group = []
        above_margin_group = []

        for element, distance in zip(element_group, distance_group):
            if distance <= inner_margin:
                within_margin_group.append(element)
            elif distance > outer_margin:
                above_margin_group.append(element)
            else:
                between_margin_group.append(element)

        within_margin.append(within_margin_group)
        between_margin.append(between_margin_group)
        above_margin.append(above_margin_group)

    return within_margin, between_margin, above_margin


OUT = group_elements_by_distance(elements, distances, inner_margin, outer_margin)

Forum_3Methods.dyn (31.0 KB)

2 Likes