mirror of
https://github.com/satwikkansal/wtfpython
synced 2024-11-22 11:04:25 +01:00
Translate Deleting list item while iterating over it example
This commit is contained in:
parent
2aa7b37540
commit
e8cd593e62
60
translations/README-ru.md
vendored
60
translations/README-ru.md
vendored
@ -2120,3 +2120,63 @@ UnboundLocalError: local variable 'a' referenced before assignment
|
|||||||
* Прочитайте [это](https://sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html) короткое, но потрясающее руководство, чтобы узнать больше о том, как работают пространства имен и разрешение областей видимости в Python.
|
* Прочитайте [это](https://sebastianraschka.com/Articles/2014_python_scope_and_namespaces.html) короткое, но потрясающее руководство, чтобы узнать больше о том, как работают пространства имен и разрешение областей видимости в Python.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### ▶ Удаление элемента списка во время прохода по списку
|
||||||
|
<!-- Example ID: 4cc52d4e-d42b-4e09-b25f-fbf5699b7d4e --->
|
||||||
|
```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), связанный со словарями.
|
||||||
|
|
||||||
|
---
|
||||||
|
Loading…
Reference in New Issue
Block a user