Different ways of getting element Ids

Hi All,

Can anyone explain me the difference between the 2 different ways of getting element Ids in the code below?

when do you use the first way to create an empty list? IDS = List[Autodesk.Revit.DB.ElementId]()

Any reference you can point me to?

Thanks

import clr

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

from System.Collections.Generic import *

elements = [UnwrapElement(i) for i in IN[0]]

IDS = List[Autodesk.Revit.DB.ElementId]()

for i in elements:
	IDS.Add(i.Id)

ElementIDs=[]

for i in elements:
	ElementIDs.append(i.Id)

OUT =IDS,ElementIDs
3 Likes

Hi @salvatoredragotta

Both versions get the ElementId using the same method, which is the .Id Property (any object that inherits from Element has it).

What’s different, is what they do with the resulting ElementId objects retrieved. The method you use, will depend what you will do with the collection of ElementIds. More details below.

The 2nd in your example, creates a list (built-in Python list) which is a generic, container native to Python, the other creates a List, a .NET data-type.


Python Lists

The list data-type (lower case L) is a native to Python/Ironpython. More details here.

What’s important is, lists don’t care what type of data they hold,
so a list can hold anything and everything: numbers, letters, variables, other lists, etc

To create them you can use:

somelist = list()

or

somelist = []

Both methods create an empty list called somelist. Some say the 2nd is faster.

To add elements (or anything else) to a list, you use the .append method:

somelist.append(SomeElemendId)
somelist.append(AnotherElemendId)

This “appends” ElementIds references to somelist
If you append other object types to the list (numbers, strings, etc), Python will not care.


.NET List

The other method (1st in your example) uses List (Capital L), which is a data-type native to the .NET languages.
One of the main differences, is that when a .NET List is created, you declare what type of objects it will hold, and later it will enforce it.

Although it’s also a container, the 2 list types are completely different data-types, so how you add/delete/retrieve/iterate will change.

The List type is not native to Python/Ironpython, so before you can use it, you have to import it from the .NET Collections assembly:

from System.Collections.Generic import List
# Imports List type from .NET's Collections.Generic Namespace
somelist = List[Autodesk.Revit.DB.ElementId]()
# Creates an empty List container that can hold only ElementIds
somelist.Add(SomeElementId)
somelist.Add(AnotherElementId)
# Adds ElementIds to the List

If you try to add any object that is not an ElementId, it will raise an exception.


In conclusion

When would you use one of the other? It depends.

Generally, you can/should use Python lists if you are just manipulating data, iterating, etc - they are more flexible, easier to use, and native to Python.

But when working with the Revit API, there instances when you are asked to pass lists/collections of objects.
in those cases, you have to create a List that holds the required type first.

For example, if you want to create a FilledRegion, Revit asks you to pass a List of CurveLoops, so you have to create a List[CurveLoop](), and add your CurveLoop objects.

I hope this helps!

13 Likes

@Gui_Talarico Thank you very much for the exhaustive explanation. :grinning:

1 Like