Генератор отдельно для наглядности сахара вынесен, конечно же. Это тоже валидный код:
comp_1 = [i for i in range(10)]
comp_2 = list(i for i in range(10))
assert comp_1 == comp_2
Почему включения быстрее циклов?
И то что лежит на поверхности (т.е. для этого даже не нужно смотреть байткод) - это изменение объектов (в данном случае изменяем экземпляр списка) и их особенности по работе с памятью:
from sys import getsizeof
result = []
size_ = getsizeof(result)
for i in range(10000):
result.append(i)
if (new_size := getsizeof(result)) > size_:
size_ = new_size
print(i, size_)
этот совет выглядит скорее вредным, потому что typing `dict[str, str]` буквально и описывает hashmap неопределенной длины, но однородного содержания.
Подводные камни прячутся в гибкости. Мы можем описать коллекцию книг как:
А можем как хэшмапу с быстрым доступом по выбранному свойству:
Но гибкость нам позволяет и сам Book описать как словарь:
Тем не менее легко выделить критерии, по которым легко признать, что у вас на руках Object:
Значения, вероятно, неоднородны (хотя легко придумать описание книги, подходящее под `dict[str, str]`)
Ключи - это не свойство значения, доступного по ключу, это свойство Object.
Длина словаря определена набором свойств описываемого Object
Таким образом, два последних пункта буквально сигнализируют о том что мы объект и его поля запихали в хэшмапу.
И такое можно делать - но желательно осознанно. Иначе по коду могут начать летать словари словарей, примерно с таким тайпингом:
В качестве же компенсации за критику присоединюсь к рекомендации причинять pydantic. Начиная с V2 он вырос на голову относительно себя:
Написан на rust (В смысле, прибавил в производительности)
Через Annotated можно делать крутяцкие валидации-сериализации и переиспользовать их
Дженерики начали работать как дженерики (в отличие от батьки-питона) - в том числе и с предыдущим пунктом.
Умеет включать в свои модели данных датаклассы и восстанавливать их при парсинге json
Имеет TypeAdapter, который позволить спарсить из json в том числе чистый dataclass, такое вот содружество.
Наверняка я что-то ещё интересного упустил, но и так вроде неплохо звучит.
у нас тут поднято уже два разных вопроса:
Генератор отдельно для наглядности сахара вынесен, конечно же. Это тоже валидный код:
И то что лежит на поверхности (т.е. для этого даже не нужно смотреть байткод) - это изменение объектов (в данном случае изменяем экземпляр списка) и их особенности по работе с памятью:
где вывод будет:
Итого, чем больше мы добавляем объектов в коллекцию, тем больше питон тратит времени на работу с памятью. Направления для изучения:
Как вообще питон обращается с памятью.
Различия по работе с памятью по встроенных типах коллекций
Вопрос в заголовке на просторах stackoverflow
Темы обширны, самых лучших ссылок под рукой нет, к сожалению, а первые попавшиеся добавлять не хочется, ведь наверняка будет источник ещё лучше.
Потому что не изменяет размер существующих объектов, в отличие от.
comprehansion - это синтаксичеcкий сахар вокруг генератора: