Ошибка алгоритма числовой фильтрации - PullRequest
0 голосов
/ 08 января 2020

Итак, я написал этот алгоритм, в котором при заданном наборе целых чисел он удалит все целые числа, кроме 0 и 7, а затем проверит, находятся ли остальные целые числа в определенном порядке, а затем вернет логическое значение. Код ниже:

def spy_game(nums):
  for i in nums:
    if i != 0:
      if i == 7:
        continue
      else:
        nums.remove(i)
    else:
      continue
  stringlist = [str(o) for o in nums]
  mystring = ''.join(stringlist)
  return '007' in mystring

spy_game([1,0,2,4,0,7,5])

Теперь проблема в том, что, если я запусту (например) spy_game([1,0,2,4,0,7,5]), он не вернет True, независимо от того, присутствует ли интересующая последовательность. После того как я решил вернуть список как таковой после процесса фильтрации, я обнаружил, что все числа, кроме тех, что в середине, отфильтрованы. Так что в этом примере, если я return nums вернусь [0, 4, 0, 7], хотя 4 должен был быть удален. Я знаю, что есть более оптимальные альтернативы этому алгоритму, но я просто хочу понять, почему он не работает. Спасибо.

Ответы [ 2 ]

2 голосов
/ 08 января 2020

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

Вы не должны изменять список во время итерации.

Вот очищенная версия

def spy_game(nums):
    ans = []
    for i in nums:
        if i == 0 or i == 7:
            ans.append(i)

    stringlist = [str(o) for o in ans]
    mystring = ''.join(stringlist)
    return '007' in mystring
0 голосов
/ 08 января 2020

Комментарий zenwraight говорит , в чем проблема: в Python вы не можете изменять список, перебирая его.

Что касается почему , документация Python обсуждает это в заметке о разделе for оператора :

Используется внутренний счетчик чтобы отслеживать, какой элемент используется следующим, и это увеличивается на каждой итерации. … Это означает, что если [l oop body] удалит текущий… элемент из последовательности, следующий элемент будет пропущен (поскольку он получает индекс текущего элемента, который уже был обработан).

В документации также описывается, что происходит, когда вы вставляете элемент в течение всего oop, и предлагается одно из возможных решений (использование фрагмента для копирования списка: for i in nums[:]: ...). В вашем случае использования это решение, вероятно, будет работать нормально, но оно значительно менее эффективно, чем параметры, которые не копируют весь список.

Лучшим решением может быть использование другого понимания списка:

nums = [i for i in nums if i == 0 or i == 7]
...