Мы продолжаем цикл лекций про numpy-программирование: первая статья, вторая и третья. Сегодня мы попробуем сгенерировать все варианты из двух списков. Конечно же есть удобная библиотека itertools, которая позволит получить нужный результат, но наша задача - написать алгоритм в новом стиле матричного программирования.
Стало уже доброй традицией формулировать задачу на конкретном примере. Не будем нарушать традиций. Пусть у нас будет два вектора по 5 элементов каждый: [1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10], а результат должен выглядеть так:
Получить результат в классическом стиле очень даже просто:
Здесь использован list comprehension, что является запрещенным приемом, особенно, если в один цикл вложен другой. Приглядитесь внимательно к результирующей матрице: каждый элемент образован соединением повторением значений первого вектора и чуть другим повторением значений второго. А в библиотеке numpy есть нужные нам функции: repeat и tile. Объединить повторения можно функцией stack. Оформим все это в виде функции:
Начнем с функции repeat, как понятно из названия, она повторяет определенный массив, опеределенное количество раз, посмотрим как она это делает:
Теперь посмотрим как это делает функция tile:
Теперь все это надо соединить наподобие функции zip, то есть первый элемент первого вектора с первым элементом второго вектора. Именно это и делает функция stack с параметром axis=1.
Если мы подадим наши исходные вектора в текущую функцию, то получим результат аналогичный ожидаемому.
В качестве домашнего задания, подумайте: можно ли как-то переделать функцию для векторов разных размеров, например, 4 и 5.