Наверняка вы часто используете генераторы списков (List Comprehension). Я тоже, даже порой злоупотребляю ими) Но что поделать, если они такие удобные!
Давайте разберёмся как работают составные итерации в генераторе списка.
Для начала посмотрим простой вид.
>>> array = [1, 2, 3, 4]
>>> [x for x in array]
Этот код просто делает копию списка. Добавляем некоторое выражение:
>>> [x*2 for x in array]
Этот генератор создаёт новый список элементы которого в 2 раза больше чем в оригинальном списке. Добавим условие:
>>> [x*2 for x in array if x%2]
Предыдущему примеру добавили фильтр, который проходят только нечётные числа.
В целом, я бы советовал на этом и остановиться. Не нужно усложнять простое!
Мы можем итерировать в генераторе сразу два списка так, чтобы каждый элемент одного списка повстречался с каждым элементом из другого.
>>> array1 = [1, 2, 3]
>>> array2 = [4, 5, 6]
>>> print([f'{i}-{j}' for i in array1 for j in array2])
['1-4', '1-5', '1-6', '2-4', '2-5', '2-6', '3-4', '3-5', '3-6']
Давайте обозначу каждый цикл условными скобками чтобы было понятней (синтаксически это неверно).
[f'{i}-{j}' (for i in array1) (for j in array2)]
Можем добавить условие и сюда? Можем!
>>> print([f'{i}-{j}' (for i in array1 if i >= 2) (for j in array2 if j < 5)])
['2-4', '3-4']
При этом во второй итерации мы можем использовать переменную из первой
>>> array = [(1, 2, 3), (4, 5, 6)]
>>> new = [y for x in array for y in x]
Кстати, мы разложили вложенные кортежи в один плоский список.
Можем ли мы использовать больше двух итераций? Да хоть десять!
>>> a1 = [9, 2, 4, 5]
>>> a2 = [4, 5, 9, 1]
>>> a3 = [5, 9, 3, 0]
>>> match = [x for x in a1 for y in a2 for z in a3 if x == y and x == z]
[9, 5]
Нашли числа которые встречаются во всех списках.
Можно еще сложней? Конечно, Python довольно многое позволяет делать.
Но, как говорят про Python: если ЭТО можно сделать то еще не значит что ЭТО нужно делать.
#tricks