Почему он не удаляет все нули из списка - PullRequest
2 голосов
/ 05 апреля 2020

Я давно не кодировал Python, а иногда я совершенно сбит с толку. Когда у меня есть массив, например, например: arr = [0, 1, 0, 3, 12] и говорят:

for i in arr:
    if i == 0:
       arr.remove(i)

, он удаляет два нуля так, как я хочу. Но если массив что-то вроде: arr = [0, 0, 1], с помощью вышеуказанного метода, один 0 останется. Так может кто-нибудь объяснить мне, почему такое поведение? Я не могу найти объяснение этому.

Ответы [ 3 ]

4 голосов
/ 05 апреля 2020

Лучше попробуйте это:

arr = [n for n in arr if n != 0]

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

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

1 голос
/ 05 апреля 2020

Я думаю, я нашел, почему ваш метод не работает. Проблема заключается в том, как вы выполняете итерацию.

В вашем примере ваша функция работает для arr = [0,1,0,3,12], но не для вашего второго массива arr2 = [0,0,2] и возвращает [0,2]. Тогда интересно исследовать один факт: во втором примере у вас есть два последовательных нулей.

Посмотрите на этот код и попробуйте выполнить it:

for i in arr:
        print('i = '+str(i))
        if(i == 0):
            arr.remove(i)

С вашим первым массивом вы заметили, что ваш вывод - тот, который вы ожидали, но это повезло. На самом деле, если вы запустите приведенный выше код, вы увидите, что он печатает в вашей консоли:

> i = 0
> i = 0
> i = 12

Итак, на самом деле это означает, что ваш оператор remove изменяет массив, который вы повторяете , После удаления вы пропускаете элемент в своем массиве.

Это означает, что вы должны предпочесть другой путь, такой как предложенный в комментариях.

Надеюсь, это поможет

0 голосов
/ 05 апреля 2020

Вы можете отфильтровать нули с помощью встроенной функции filter :

arr = list(filter(None, arr))

, на которую следует обратить внимание, если вы используете функцию filter с None в качестве первого Этот параметр будет применяться bool к вашим элементам, если у вас есть такие элементы, как None, 0 или пустая строка '', результат будет таким же, False, и все эти элементы будут отфильтрованы, для Из соображений безопасности вы можете использовать:

arr = list(filter(lambda x: x != 0 , arr))
...