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)