Цикл статей который стоит прочитать - https://habr.com/en/post/319164/ .
Замечания к статьям:
('a', 1) in my_dict.items() кажется что здесь поиск будет не за O(1). Надо бы проверить. Проще узнать просто сравнить значение по ключу.Большинство объектов в питоне просто лежат в оперативной памяти, а каждая переменная представляет из себя ссылку на участок оперативной памяти где он лежит. Это может привести к проблемам, если вы сошлетесь на один и тот же изменяемый объект разными переменными.
a = [1, 2, 3, 4]
b = a
Обе переменные указывают на один и тот же участок в памяти, поэтому если мы теперь обратимся к объекту в переменной b и изменим его, то изменится и тотже объект, на который ссылается переменная a .
a = [1, 2, 3, 4]
b = a
b[2] = "Oh shit"
print(a) # [1, 2, "Oh shit", 4]
Возможно это очевидно, но на всякий случай. Если мы сделаем
a = [1, 2, 3, 4]
b = a
b = [2, 3, 4]
Это переприсваивание b никак не скажется на списке a, так как в этом случае мы просто говорим переменной b смотреть на дргуой список в памяти, а не обращаемся к объекту, на который указывает b и меняем его.
Изменять объект на который указывает переменная можно только через методы этого объекта или обращаясь напрямую к его аттрибутам. Присвоение чего-то в переменную просто заставляет переменную указывать на другой место в памяти.
Как копировать списки, описано в статье. Ссылки на информацию про Big O notation там есть.
Вот на русском простенькая статья есть, но слишком поверхностная. К тому же вставка в список в основном занимает не O(n), а O(1), если это вставка в конец списка.
Сколько стоят операции над list, set и dict в Python? Разбираемся с временной сложностью
В питоне два типа циклов while и for , первый такой же как и в большинстве распространенных языков.
Про цикл while можно почитать в документации питона/на любом сайте, там все очень просто.