Почему не безопасно изменять последовательность, повторяющуюся?

Небезопасно изменять последовательность, повторяющуюся в цикле (это может произойти только для изменяемых типов последовательностей, таких как списки). Если вам нужно изменить список, который вы повторяете (например, чтобы дублировать выбранные элементы), вы должны перебирать копию. Нотация среза делает это особенно удобным:

>>> for x in a[:]: # make a slice copy of the entire list ... if len(x) > 6: a.insert(0, x) ... >>> a ['defenestrate', 'cat', 'window', 'defenestrate'] 

почему это небезопасно просто for x in a ?

3 Solutions collect form web for “Почему не безопасно изменять последовательность, повторяющуюся?”

Не становясь слишком техничным:

Если вы выполняете итерацию через изменяемую последовательность в Python, и последовательность изменяется во время ее повторения, не всегда ясно, что произойдет. Если вы вставляете элемент в последовательность во время итерации через него, что теперь разумно будет считаться «следующим» элементом в последовательности? Что делать, если вы удаляете следующий объект?

По этой причине повторение с помощью изменяемой последовательности при ее изменении приводит к неуказанному поведению. Все может произойти, в зависимости от того, как именно реализован список. 🙂

Это распространенная проблема на многих языках. Если у вас есть линейная структура данных, и вы повторяете ее, что-то должно отслеживать, где вы находитесь в структуре. Это может быть текущий индекс или указатель, но это какой-то палец, указывающий на «текущее место».

Если вы изменяете список во время итерации, этот курсор, скорее всего, будет неправильным.

Общей проблемой является то, что вы удаляете элемент под курсором, все слайд вниз, следующая итерация цикла увеличивает курсор, и вы случайно пропустили элемент.

Некоторые реализации структуры данных предлагают возможность удалять элементы во время итерации, но большинство из них этого не делают.

Когда вы изменяете коллекцию, которую вы выполняете, итератор может вести себя неожиданно, например, пропускать элементы или возвращать один и тот же элемент дважды.

Когда я запускаю этот код, этот цикл бесконечно цикличен:

 >>> a = [ 'foo', 'bar', 'baz' ] >>> for x in a: ... if x == 'bar': a.insert(0, 'oops') 

Это связано с тем, что итератор использует индекс для отслеживания того, где он находится в списке. Добавление элемента в начале списка приводит к тому, что элемент «бар» возвращается снова вместо того, чтобы итератор переходил к следующему элементу.

  • howto uncompress gzipped данные в массиве байтов?
  • Pythonic способ удаления каталогов из списка файлов
  • Что такое каталог сайтов-пакетов python?
  • Войдите в Facebook, используя запросы python
  • Список как ключ для словаря
  • IbPy: как извлечь ответ API в переменную
  • Устанавливает устаревшее предупреждение модуля
  • Декоратор для конкретных строк кода вместо целого метода?
  • как перезагрузить модуль в python версии 3.3.2
  • Как найти отсутствующие даты в списке отсортированных дат?
  • Python __str__ и списки
  •  
    Interesting Posts for Van-Lav

    Как получить атрибут от объекта, если у меня есть имя атрибута в строке?

    pandas.to_datetime ОШИБКА

    Борьба с дисбалансом класса в двоичной классификации

    Amazon EC2 AMI предварительно сконфигурирован с помощью Django Stack

    В Python, как вы разбиваете список на четные куски, начиная с последнего элемента из предыдущего фрагмента?

    Sklearn Pipeline – Как наследовать get_params в пользовательском Transformer (не Estimator)

    Почему мой дизайнер Django не получает запрос, переданный ему?

    Прогноз предсказания тензора Mninst с использованием внешнего изображения не работает

    Python – urllib2 & cookielib

    Python – Перспективное преобразование для OpenCV от угла поворота

    Как исправить ошибки PyDev «Неопределенная переменная из импорта»?

    Трясогузка: проблема развертывания – запрос KeyError 'on / admin

    Преобразование CSV в JSON (в определенном формате) с использованием Python

    pthread с обратным вызовом на python VM

    Как предотвратить публикацию совместно используемой библиотеки C на stdout в python?

    Python - лучший язык программирования в мире.