Получение списка данных из свойств объектов с использованием list comprehension

Большинство объектов в Blender имеют в своей структуре множество списков данных. Например, внутри объекта “меш” присутствуют списки с набором вертексов этого меша, набором ребер, набором полигонов. А в структуре каждого вертекса присутствует, например, список с его координатами по осям X, Y и Z.

Для доступа к таким внутренним спискам данных обычно приходится составлять циклы из нескольких уровней вложенности. Однако в языке Pythoh, который используется в Blender API, существует удобная возможность формировать такие вложенные циклы одной строкой – list comprehension.

Рассмотрим простой пример: пусть у нас на меше есть несколько выделенных полигонов, и нам нужно найти максимальную координату по оси Z среди точек этих полигонов.

В простейшем случае мы создадим цикл сначала по выделенным полигонам:

Внутри него создадим еще один цикл уже по вертексам, принадлежащим выделенным полигонам:

И уже только внутри него мы сможем получить доступ к координатам каждого вертекса. Получается следующая структура кода из четырех уровней вложения:

Если же использовать list comprehension, можно все это выражение записать в одну строку.

List comprehension в Python работает следующим образом: один уровень цикла, формирующий список, записывается в строку в квадратных скобках. Слева указывается получаемое выражение для каждой итерации цикла, справа, при необходимости – дополнительное условие.

new_list = [expression for item in iterable (if condition)]

Так первый и второй уровни нашего кода можно представить следующим выражением в одну строку:

Разложив при помощи list comprehension в строку только первые два уровня, мы получаем список списков – каждый элемент нового списка является сам по себе списком с координатами вертексов.

Мы могли бы еще раз пробежаться по полученному списку циклом:

Уровень вложенности стал чуть меньше, однако еще осталось пространство для дальнейшего сжатия, так как list comprehension в Python поддерживает несколько уровней вложенности.

Каждый последующий уровень записывается слева направо с опциональным указанием условий. А выражение слева может оперировать переменными с последнего (чаще всего), или же с каждого из уровней.

Продолжим превращать наш код в однострочное выражение.

Слева мы указываем финальное выражение для получения координаты Z вертекса. Далее, слева направо указываем выражения на каждом уровне циклов и условия, если они есть.

И в итоге мы получаем следующую строчку кода:

В результате мы получили точно такой же список значений, как и при использовании многоуровневых циклов.

Давайте рассмотрим еще один пример: пусть у нас есть несколько выделенных точек на меше, и нам нужно получить список ребер, выходящих из этих точек, которые не выделены.

Для быстрого получения связанных с вертексами ребер будем использовать объект bmesh.

Сначала получим список не выделенных ребер обычным путем при помощи вложенных циклов:

А затем получим этот список при помощи list comprehension, записывая все в одну строку.

Слева пишем конечное выражение – что именно мы получаем в списке. В нашем случае это ребро – edge. Далее, слева направо указываем каждый уровень плюс условие.

Таким образом мы получили тот же самый список нужных нам ребер, использовав всего одну строку кода.

0 0 голоса
Article Rating
Подписаться
Уведомить о
guest

0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии