Group By Key in python

Hello,

Trying to create a python script to identify group instances with excluded elements.

Not being able to figure out how to Group By Key the way it shows in the image just using python.

If I try to include the lines below I get a different datatype that I cannot understand.

#test to Group By Key
instances=[]
types=[]
groupped=[]
uniquekeys=[]
for i in groups:
	instances.append(i[0])
	types.append(i[1])

for k, g in groupby(groups, lambda x:x[0]):
	groupped.append(g)
	uniquekeys.append(k)

Thank you
J

full python script here

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager

from RevitServices.Transactions import TransactionManager

from itertools import groupby

#Inputs
doc = DocumentManager.Instance.CurrentDBDocument
fec = FilteredElementCollector

type_elems = []

modelGroups = fec(doc).OfCategory(BuiltInCategory.OST_IOSModelGroups).WhereElementIsNotElementType().ToElements()

elems=UnwrapElement(modelGroups)
groups=[]

for ele in elems:
	eleID=ele.Id
	eleName=ele.Name
	if "(members excluded)" in eleName:
		group=[ele,ele.GroupType]
		groups.append(group)
	else:
		group=""

#works fine up to here

#test to Group By Key
instances=[]
types=[]
groupped=[]
uniquekeys=[]
for i in groups:
	instances.append(i[0])
	types.append(i[1])

for k, g in groupby(groups, lambda x:x[0]):
	groupped.append(g)
	uniquekeys.append(k)

#Assign your output to the OUT variable.
OUT = [groups, groupped, uniquekeys]
1 Like

Before calling groupby you need to sort your data first. This sorts groups in place by the Id of the group type

groups.sort(key=lambda x: x[1].Id)

And then within groupby you are currently returning the iterator instead of a list of elements. You can convert it to a list by wrapping it with list(). You will also need to use the Id of the group type rather than the group type itself in the lambda expression

for k, g in groupby(groups, lambda x:x[1].Id):
	groupped.append(list(g))
	uniquekeys.append(k)

So the last part of your script should look like this

#works fine up to here

#test to Group By Key
groupped=[]
uniquekeys=[]

groups.sort(key=lambda x: x[1].Id)

for k, g in groupby(groups, lambda x:x[1].Id):
    groupped.append(list(g))
    uniquekeys.append(k)

#Assign your output to the OUT variable.
OUT = [groups, groupped, uniquekeys]

Hope this helps,
Thomas

3 Likes

Thank you @Thomas_Corrie.

I have edited my code but I am still getting an “IronPython.Modules…” instead of the actual elements.

My goal is to get an output similar to the one in the Watch node in the blue group.

Thank you
J

Can you show your revised Python code?

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager

from RevitServices.Transactions import TransactionManager

from itertools import groupby

#Inputs
doc = DocumentManager.Instance.CurrentDBDocument
fec = FilteredElementCollector

type_elems = []

modelGroups = fec(doc).OfCategory(BuiltInCategory.OST_IOSModelGroups).WhereElementIsNotElementType().ToElements()

elems=UnwrapElement(modelGroups)
groups=[]

for ele in elems:
	eleID=ele.Id
	eleName=ele.Name
	if "(members excluded)" in eleName:
		group=[ele,ele.GroupType]
		groups.append(group)
	else:
		group=""

#works fine up to here

#from https://forum.dynamobim.com/t/group-by-key-in-python/39145/2 by Thomas_Corrie
groupped=[]
uniquekeys=[]

groups.sort(key=lambda x: x[1].Id)

for k, g in groupby(groups, lambda x:x[0]):
	groupped.append(g)
	uniquekeys.append(k)

#Assign your output to the OUT variable.
OUT = groups

You’re still appending g directly to groupped. As I mentioned above you need to convert it to a list by wrapping it with list(). Also you’re grouping by x:x[0] in the lambda expression and I think you really want x:x[1].Id

for k, g in groupby(groups, lambda x:x[1].Id):
    groupped.append(list(g))
    uniquekeys.append(k)