Problem with obtaining Unique Items in Lists with multiple Levels

Good morning from Italy, in my latest script i’m trying to extract all the instances, grouped by room and then by family, that share the same value of a certain parameter. As you can see in the picture attached i am trying to obtain in the list @L2 in Element.GetParameterValueByName a match between the elements in those sublists and the sublists @L2 in List.FilterByBoolMask in order to obtain something like this (always considering the picture) :
List 0 @L2: TRUE false TRUE false false false false false false false false false
List 1 @L2: false TRUE false TRUE

I already tried with the nodes “==” and “String.Contains” and also by changing the levels in input, but the desired structure never comes out, do you have any idea on how can i obtain it?
Thanks in advance

Hiya,

Apologies, I don’t think I understand exactly what you are after…

As I understand it, you are confused as to why the lists don’t match between the Element.GetParameterValueByName and the List.CountOccurances?

The List.CountOccurances is outputting uniqueElements? Is that the problem?

From what you are describing, I would probably use ‘GroupByKey’ rather than a Boolean Mask… Probably in conjunction with some list.flatten and list.chopping? Does that sound useful?

Hopefully that helps a little :slight_smile:

Kind regards,

Mark

1 Like

Hi, sorry if i was not clear enough.
I’ll try to explain a little bit better…
What i’d like to obtain is something like a “==” or “String.Contains” node, to which i would like to connect both the “Element.GetParameterValueByName” and the “List.FilterByBoolMask” nodes, in order to obtain a list, with its sublists, that has the same number of elements as the ones in the “Element.GetParameterValueByName”, so for example 12 elements in the first sublist (RED), 4 elements in the second sublist (BLUE), in which it shows me with a True/False which value matches with the one that i have in the relative sublist in the “List.FilterByBoolMask” node.

EXAMPLE:
in sublist 0 in Element.GetParameterValueByName (RED) i have 12 values, and two of them are “3”;
in sublist 0 in List.FilterByBoolMask (RED) i have the value “3”, because it is not unique in the previous list;
i would like to obtain something that tells me, for all the 12 elements, if those 12 are “3” or not, in this case i would like to obtain two “True” values, for the one and for the third element of that sublist.

I hope i’ve been more clear now, and thanks for your reply!

Yes! That’s it! Sorry but i’m italian and it’s not so easy to put in simple words things inside Dynamo!

Hold on, something was wrong, I’ll edit it and post it again.

No problem, i took a look before your edit and it was basically what i was searching for!

Okay, try this in your script and see if this it was what you were looking for.

grouped_itms = Dictionary.ValueAtKey(List.GroupByKey(lst<2>,lst<2>),"groups");
unique_itms = Dictionary.ValueAtKey(List.GroupByKey(lst<2>,lst<2>),"unique keys");
count = List.Count(grouped_itms<1><2>);
duplicated_itms = List.Clean(count>1?unique_itms:null,false);

List.Contains(x<1>,y<1><2>);

1 Like

Thanks again! I will try as soon as possible and i’ll let you know!

1 Like

It works with ==, you just have to use the appropriate list levels.

1 Like

It works perfectly for the first three sublists, in which i have only one value to find, but as you can see in the sublist 3, in which i would like to obtain both 01 and 02 as True, it only states that 01 is true… any advice for this?

Ah. Yeah, your list structure becomes too complicated there. You could modify the list structure to check for each value individually, but @Mark.Ackerley’s suggestion of GroupByKey is much simpler. It will give you the unique values and group them, meaning you just filter the groups for those with more than one item.

So, in this case you suggest to apply directly the script suggested by @Mark.Ackerley ? Or to use it in combination with “==” ?

They are two different solutions to the same problem. I only suggested the == solution because it was what you had already tried. In order to do that, you have to get the list structure to check each item individually.

@Mark.Ackerley’s solution is actually a better solution overall (in my opinion) but requires you to rewrite part of your graph. That’s certainly not a bad thing. Just something to note. It also filters the actual items for you and skips the need for a second bool mask.

By appling the “==” node with the “List.Chop” did you obtained True values also for the second value of the sublist? (The one that was chopped).
Because in my case the result is still the same as before… I guess that the best idea is really to reorganize everything and apply the script, but my question is:
the second picture you have posted is the equivalent of @Mark.Ackerley script without Code Block? Or is a third way?

Also, i would like to underline the fact that, due to the fact that this script will be used for Model Checking based on Guidelines, the desirable structure would be the one in the first picture, because then i would apply the Boolean Mask to the list of objects, in order to create an Excel with the ID and the name of the objects that share the same value of the parameter

If I understood correctly your final goal, the approach I suggest you to try works fine even for your sublist 3.

This is perfect! But why when i write down the script it gives me this error? It is because of Orchid package? (As i suggest from the error info)

I don’t know because I don’t have Orchid, but try to put DSCore. before List and see what happens.

grouped_itms = Dictionary.ValueAtKey(DSCore.List.GroupByKey(lst<2>,lst<2>),"groups");
unique_itms = Dictionary.ValueAtKey(DSCore.List.GroupByKey(lst<2>,lst<2>),"unique keys");
count = DSCore.List.Count(grouped_itms<1><2>);
duplicated_itms = DSCore.List.Clean(count>1?unique_itms:null,false);

DSCore.List.Contains(x<1>,y<1><2>);

Hi, i finally managed to apply the code you wrote to my model, but both of the codes gave me an error. So i tried to apply both of them to the same list you created in your example, in order to check if the error was depending on the input data or in the code i wrote, and also in this case both the codes gave me an error (as you can see in the picture); the first error is:
" Warning: Internal error, please report: Dereferencing a non-pointer "
and the second one is:
" Warning: Cannot find static method or constructor DSCore.List.Contains() ".
Maybe the fact that Dictionary.ValueAtKey is in black and not in blue, as in your case, is the key to solve this problem?
(i have no experience of Phyton so i don’t understand properly the various expressions and colors)
Thanks in advance!

I don’t know what is the problem, maybe it can be your Dynamo version or it can be Orchid like you mentioned. Now, try to use this and see if it works:

def check(lst):
	result = lst[:]
	duplicates = [set([i for i in sublst if sublst.count(i)>1]) for sublst in lst]
	for j in range(len(lst)):
		for idx,itm in enumerate(lst[j]):
			if itm in duplicates[j]:
				result[j][idx]=True
			else:
				result[j][idx]=False
	return result
		
OUT = check(IN[0])