Про генераторы и итераторы
Мне когда-то советовали прочитать книжку Лутца по питону, но я ее забросила. Теперь мне нечего было делать, и я снова решила к ней вернуться) И тут я как осознала!
📝 Сделаем одно упражнение. Возьмем список, отберем только четные числа двумя способами:
`lst = [1, 2, 3, 4] l1 = [x for x in lst if x % 2 == 0] l2 = (x for x in lst if x % 2 == 0)
print(type(l1))
#print(type(l2))
#А теперь дважды материализуем:
`print(list(l1)) print(list(l1))
#[2, 4] #[2, 4]print(list(l2)) print(list(l2))
#[2, 4] #[]Список хранит все в памяти, занимает оперативку, и мы можем его вызывать сколько угодно раз. А генератор закончился и всегда будет пустым🔲 ➖➖➖➖
Если мы попробуем сделать то же самое ручками, то есть еще интересный нюанс. Сделаем два итератора - для функции range и нашего генератора l2. Сначала вызовем первый, потом второй:
`r = range(2) i1 = iter(r) i2 = iter(r) print(next(i1))
#0print(next(i2))
#0 - зановоl2 = (x for x in lst if x % 2 == 0) i1 = iter(l2) i2 = iter(l2) print(next(i1))
#2print(next(i2))
#4 - продолжили🌀 Прикол в том, что у range итераторов может быть много, как будто они передаются по значению. А в остальных случаях как будто по ссылке - когда изменяется одна, изменяется и другая.
По сути в тех случаях, когда нам не нужно несколько раз обращаться к одним данным, мы спокойно можем использовать генератор✅```