Wyrażenia listowe (list comprehensions) są bardzo przydatną funkcjonalnością języka Python, która umożliwia szybkie generowanie list na podstawie wartości w istniejących kolekcjach. Można powiedzieć, że wyrażenia listowe pozwalają filtrować istniejące listy.
Prosta składnia pozwala na szybkie utworzenie wymaganej kolekcji w obrębie jednej linijki kodu. Wykorzystanie wyrażeń listowych podczas skryptowania w ANSYS Mechanical znacząco przyspiesza wykonywanie kodu oraz zwiększa jego czytelność.
Składnia
Wyrażenia listowe pozwalają – w sposób szybki i czytelny – generować listy obiektów drzewa, geometrii czy elementów skończonych w środowisku ANSYS Mechanical.
Mimo prostej i czytelnej składni, sprawia ona problemy początkującym użytkownikom. Dlaczego? Popatrzmy na klasyczny przykład filtrowania obiektów typu NamedSelection z wykorzystaniem zwykłej pętli:
nsList = []
for ns in ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory):
If ‘_BC’ in ns.Name:
nsList.append(ns)
Powyższy kod tworzy listę zawierającą wszystkie obiekty drzewa analizy o typie NamedSelection. Następnie – w prostej pętli – sprawdzamy, czy nazwa obiektu NamedSelection spełnia kryterium nazwy (nazwa musi zawierać ciąg znaków ‘_BC’). Jeśli kryterium jest spełnione, dodajemy obiekt do utworzonej wcześniej listy o nazwie nsList.
Zróbmy to samo z wykorzystaniem wyrażenia listowego:
nsList = [ns for ns in ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory) if ‘_BC’ in ns.Name]
Różnice są widoczne od razu.
- całość zamyka się w jednej linijce;
- nie musimy tworzyć pustej listy, którą następnie wypełnimy obiektami spełniającymi kryteria;
- mamy do czynienia ze zmienioną kolejnością komend.
Popatrzmy na uproszczone schematy obu metod. Poszczególne kroki są oznaczone kolorami:
Dla każdego obiektu w liście jeśli spełnia warunek dodaj obiekt do listy wynikowej
Dodaj obiekt do listy wynikowej dla każdego obiektu w liście jeśli spełnia warunek
Widzimy wyraźnie, że dodanie obiektu do listy wynikowej jest pierwszym elementem definiowanym z wykorzystaniem wyrażeń listowych, a w przypadku zwykłej pętli – ostatnim. Odwrócona kolejność wydaje się główną przyczyną problemów ze zrozumieniem składni wyrażeń listowych.
Mam nadzieję, że powyższe wyjaśnienia pomogą początkującym użytkownikom opanowanie tej niezwykle przydatnej – i jak zobaczymy poniżej – bardzo wydajnej funkcjonalności języka Python.
Praktyczne zastosowania w ANSYS Mechanical
Poniższy przykład pozwala szybko uzyskać dostęp do geometrii o określonej grubości i nazwie. Jak widzimy, wyrażenia listowe umożliwiają sprawdzenie wielu kryteriów w obrębie jednej operacji.
[b for b in ExtAPI.DataModel.GetObjectsByType(DataModelObjectCategory.Body) if body.Thickness == Quantity(’10 [mm]’) and 'Shell’ in body.Name]
Kolejny przykład pokazuje, jak zawęzić listę węzłów uwzględniając położenie w przestrzeni oraz wykonanie operacji na węzłach spełniających kryteria. W efekcie, otrzymana lista będzie zawierała nie węzły, a obiekty typu Vector3D utworzone w oparciu o koordynaty x,y,z węzłów spełniających kryteria.
[Vector3D(n.X, n.Y, n.Z) for n in nodeList if n.X >= 40.0 and n.Y <=-5.0]
Wydajność
Na koniec „wisienka na torcie” czyli wydajność. Operacja filtrowania listy zawierającej 173 000 węzłów trwa o połowę krócej, kiedy korzystamy z wyrażeń listowych:
Klasyczna pętla: 0.390 s
Wyrażenie listowe: 0.199 s
Zachęcamy do zapoznania się z pozostałymi wpisami z serii o skryptowaniu:
Konfiguracja wyświetlania wyników z wykorzystaniem języka Python
Jak efektywnie korzystać z pomocy podczas skryptowania w ANSYS Mechanical
Autor: Bartosz Płochocki, MESco sp. z o.o.