Comprehension и генераторы
Компактный способ создать массив по правилу — array comprehension, знакомый по Python, но с нюансами.
Comprehension — выражение, которое строит массив, применяя формулу к каждому значению из диапазона или коллекции.
Базовый синтаксис
Comprehension записывается в квадратных скобках: «выражение for переменная in коллекция».
squares = [x^2 for x in 1:5]
println(squares)Вывод:
[1, 4, 9, 16, 25]
Это короче и часто быстрее, чем заводить пустой массив и наполнять его в цикле через push!.
С условием-фильтром
Можно добавить if, чтобы оставить только подходящие элементы:
evens = [x for x in 1:10 if x % 2 == 0]
println(evens)Вывод:
[2, 4, 6, 8, 10]
Вложенные comprehension
Два цикла подряд создают многомерный результат — это удобно для матриц:
table = [i * j for i in 1:3, j in 1:3]
println(table)Вывод:
[1 2 3; 2 4 6; 3 6 9]
Здесь получилась матрица 3×3 — таблица умножения. Запятая между двумя for создаёт именно матрицу, а не плоский вектор.
Генераторы: ленивая версия
Если убрать квадратные скобки и оставить круглые (или передать выражение прямо в функцию), comprehension становится генератором — он не создаёт массив, а выдаёт значения по одному. Это экономит память, когда нужно лишь просуммировать или найти максимум:
total = sum(x^2 for x in 1:1000)
println(total)Вывод:
333833500
Здесь миллион квадратов не материализуется в массив — sum получает их по одному.
Как работает под капотом
Comprehension в Julia — это синтаксический сахар над циклом, но с важным преимуществом: компилятор часто может заранее определить тип элементов и сразу выделить массив нужного типа и размера. Поэтому результат comprehension обычно имеет конкретный тип вроде Vector{Int64}, а не Vector{Any}, что важно для скорости. Генератор же не выделяет память под результат вовсе — значения вычисляются лениво в момент потребления.
Частые ошибки
Распространённая путаница — разница между [... for i in A, j in B] (создаёт матрицу) и [... for i in A for j in B] (создаёт плоский вектор из вложенных циклов). Запятая даёт декартово произведение в виде матрицы, два отдельных for — «выпрямленный» вектор. Выбирайте форму осознанно.
Итоги
- Comprehension компактно строит массив:
[x^2 for x in 1:5]. - Фильтр добавляется через
if:[x for x in 1:10 if x % 2 == 0]. - Запятая между
forсоздаёт матрицу; дваfor— плоский вектор. - Генератор (без квадратных скобок) ленив и экономит память.