diff --git a/translations/README-ru.md b/translations/README-ru.md index 726b3ea..b102077 100644 --- a/translations/README-ru.md +++ b/translations/README-ru.md @@ -2120,3 +2120,63 @@ UnboundLocalError: local variable 'a' referenced before assignment * Прочитайте [это](https://sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html) короткое, но потрясающее руководство, чтобы узнать больше о том, как работают пространства имен и разрешение областей видимости в Python. --- + + +### ▶ Удаление элемента списка во время прохода по списку + +```py +list_1 = [1, 2, 3, 4] +list_2 = [1, 2, 3, 4] +list_3 = [1, 2, 3, 4] +list_4 = [1, 2, 3, 4] + +for idx, item in enumerate(list_1): + del item + +for idx, item in enumerate(list_2): + list_2.remove(item) + +for idx, item in enumerate(list_3[:]): + list_3.remove(item) + +for idx, item in enumerate(list_4): + list_4.pop(idx) +``` + +**Результат:** +```py +>>> list_1 +[1, 2, 3, 4] +>>> list_2 +[2, 4] +>>> list_3 +[] +>>> list_4 +[2, 4] +``` + +Есть предположения, почему вывод `[2, 4]`? + +#### 💡 Объяснение: + +* Никогда не стоит изменять объект, над которым выполняется итерация. Правильным способом будет итерация по копии объекта, и `list_3[:]` делает именно это. + ```py + >>> some_list = [1, 2, 3, 4] + >>> id(some_list) + 139798789457608 + >>> id(some_list[:]) # Notice that python creates new object for sliced list. + 139798779601192 + ``` + +**Разница между `del`, `remove` и `pop`:** +* `del var_name` просто удаляет привязку `var_name` из локального или глобального пространства имен (поэтому `list_1` не затрагивается). +* `remove` удаляет первое подходящее значение, а не конкретный индекс, вызывает `ValueError`, если значение не найдено. +* `pop` удаляет элемент по определенному индексу и возвращает его, вызывает `IndexError`, если указан неверный индекс. + +**Почему на выходе получается `[2, 4]`? +- Проход по списку выполняется индекс за индексом, и когда мы удаляем `1` из `list_2` или `list_4`, содержимое списков становится `[2, 3, 4]`. Оставшиеся элементы сдвинуты вниз, то есть `2` находится на индексе 0, а `3` - на индексе 1. Поскольку на следующей итерации будет просматриваться индекс 1 (который и есть `3`), `2` будет пропущен полностью. Аналогичное произойдет с каждым альтернативным элементом в последовательности списка. + +* Объяснение примера можно найти на [StackOverflow](https://stackoverflow.com/questions/45946228/what-happens-when-you-try-to-delete-a-list-element-while-iterating-over-it). +* Также посмотрите на похожий пример на [StackOverflow](https://stackoverflow.com/questions/45877614/how-to-change-all-the-dictionary-keys-in-a-for-loop-with-d-items), связанный со словарями. + +---