Ошибка: индекс списка вне допустимого диапазона

Я новичок в Python и программировании вообще и пытаюсь решить задачу на codingbat.com (проблема называется "array_front9" в разделе "Разминка-2").

Проблема заключается в следующем: «Учитывая массив целых чисел, верните True, если один из первых 4 элементов массива равен 9. Длина массива может быть меньше 4».

Вот мой код, который работает, если я создаю список, а затем запускаю его локально (на codingbat.com необходимо создать функцию, но я не создаю функцию для локального тестирования своего кода):

arr = [14,9,28,55,66,33,789,4548]

    for i in range (4):

        if arr[i] == 9:

            print('True')

    print('False')*

Вот код, который я пытаюсь запустить на codingbat.com, но получаю сообщение об ошибке «Ошибка: индекс списка вне диапазона»:

def array_front9(arr):

    for i in range(4):

        if arr[i] == 9:

            return True

     return False

Вот решение согласно codingbat.com:

def array_front9(nums):
  # First figure the end for the loop
      end = len(nums)
          if end > 4:
              end = 4

for i in range(end):  # loop over index [0, 1, 2, 3]
    if nums[i] == 9:
      return True
    return False

Вот текущий URL-адрес для этой задачи: http://codingbat.com/prob/p110166.

Может ли кто-нибудь указать мне, что я делаю неправильно?


person lukap    schedule 30.08.2016    source источник
comment
Основное различие между кодом codingbat.com и вашим кодом заключается в том, что оператор return False. codingbat.com return False находится внутри цикла for, где, как и в вашем коде, return False находится снаружи цикла for. Есть гораздо лучшие способы сделать это. вы можете просто проверить if 9 in arr[0:4]   -  person be_good_do_good    schedule 30.08.2016
comment
Мне очень нравится решение с петлей IF!   -  person lukap    schedule 30.08.2016
comment
Я также предоставил ответ, основанный на этом, если он вам нравится и полезен для вас, проголосуйте за него / примите его как ответ.   -  person be_good_do_good    schedule 30.08.2016


Ответы (8)


Проблема гласит: «Длина массива может быть меньше 4». Ваш код в настоящее время предполагает, что массив имеет длину не менее 4. Однако, если i больше, чем последний индекс списка, будет выбрано IndexError.

Сначала вы должны проверить, является ли len(arr) < 4, и вернуть False, если это так.

person Karin    schedule 30.08.2016

В задаче указано, что длина массива может быть меньше 4. Вы просто перебираете массив. Вы должны сначала проверить, является ли array по крайней мере length 4. Если array меньше 4, то итерация выполняется только по длине array.

n = 4

if len(arr) < 4:
    n = len(arr)

for i in range(n):
    #...Your code...
person Shubham Vasaikar    schedule 30.08.2016
comment
Вы можете просто удалить все свои строки кода и ввести: for item in arr: - person Tristan; 30.08.2016
comment
Да, но проблема специально просит вас проверить только первые 4 элемента. Поэтому я подумал, зачем тратить время на повторение всех элементов, когда требуются только первые 4. - person Shubham Vasaikar; 30.08.2016

Просто проверьте это выражение:

9 in arr[:4]

Я объясняю:

Как указывали другие, ваш массив может быть короче 4 элементов, и в этом случае индексация, скажем, 3, четвертого числа, вызовет IndexError.

Но давайте воспользуемся тем свойством, что slicing не вызовет исключения, то есть:

In [232]: a = [1, 2]

In [233]: a[:10]
Out[233]: [1, 2]

В приведенном выше примере я взял срез от начала массива до 10-го элемента и не получил исключения, но Python вернул весь список.

Таким образом, вы можете сделать проверку так же просто, как:

9 in arr[:4]

и это все!

person Israel Unterman    schedule 30.08.2016
comment
Это комплексное решение. Хотя конечно не плохой. Но для новичка. - person Tristan; 30.08.2016
comment
«Вход» не рассматривается во многих учебниках для начинающих. И нарезки, наверное, тоже нет. - person Tristan; 30.08.2016

Вы используете range(4). Таким образом, он всегда будет искать 4 числа. Поэтому, когда есть только три числа, он все равно будет искать четвертое. Четвертого не существует, поэтому выдает ошибку.

Вместо этого вам нужно увидеть, какова длина списка, а затем перебрать эту длину.

Как это:

for i in range(len(arr)): 
    if arr[i] == 9:

Или, что еще проще, вы можете перебрать список следующим образом:

for list_item in arr:
    if list_item == 9:  # you don't even have to use the [i]
person Tristan    schedule 30.08.2016

Вы должны получить минимальную длину проверки входного списка:

def array_front9(nums):
    return 9 in nums[:min(4,len(nums))]
person acw1668    schedule 30.08.2016

Более простым решением этой проблемы будет:

if len(arr) > 4:
    if 9 in arr[0:4]:
        return True
    else:
        return False
else:
    print('Array length is shorter than 4')
    return False

Если вы хотите проверить наличие 9, даже если длина списка меньше 4, то ниже приведено решение:

def check(arr):
    max = 4 if len(arr) >= 4 else len(arr)

    if 9 in arr[0:max]:
       return True
    else:
        return False

print check(arr)
person be_good_do_good    schedule 30.08.2016
comment
Это будет работать только тогда, когда список больше четырех, что не так. - person Tristan; 30.08.2016
comment
Это также должно работать для списков, меньших или равных четырем. - person Tristan; 30.08.2016
comment
@TristanT, я сначала проверяю длину массива, прежде чем проверять список. Только если оно больше 4, я иду внутрь. - person be_good_do_good; 30.08.2016
comment
@TristanT, я добавил редактирование для обработки списков длиной менее 4. Пожалуйста, проверьте и проголосуйте за / удалите против - person be_good_do_good; 30.08.2016

Спасибо за все ваши ответы, они были действительно полезны!

Я решил использовать цикл IF вместо цикла FOR, вот так:

def array_front9(arr):

    if 9 in arr[0:4]:

        return True

    return False

Насколько я вижу, это решение работает независимо от длины списка, и кажется, что оно соответствует определению проблемы, то есть «независимо от длины списка, если любой из первых четырех элементов равно 9, вернуть True".

person lukap    schedule 30.08.2016

Проблема заключается в том, "проверить первые четыре числа в списке, чтобы увидеть, является ли какое-либо из них числом 9".

Теперь, если в списке меньше 4, то автоматически проверка не пройдет:

if len(arr) < 4:
  return false

Далее нужно проверить, содержат ли первые четыре элемента девять. Есть много способов сделать это, один из самых простых:

for i in arr[:4]:
  if i == '9':
     return true

Объедините два:

def check_for_nine(arr):

  if len(arr) < 4:
     return false

  for i in arr[:4]:
    if i == '9':
       return true

Проблема с вашим первоначальным подходом заключается в том, что вы устанавливаете длину равной 4 и предполагаете, что как минимум массив будет иметь 4 элемента. Если в массиве 3 элемента, то ваш код работать не будет.

Чтобы избежать этого, не предполагайте определенную длину. Если вы используете нарезку, вы гарантированно получите максимум 4 элемента.

Вот пример этого:

>>> i = [1,2]
>>> i[:4]
[1, 2]

Несмотря на то, что i содержит только два элемента, срез до 4 работает и не вызывает ошибки. Как только i будет иметь более 4 элементов, он ограничится первыми четырьмя:

>>> i = [1,2,3,4,5,6,7,8]
>>> i[:4]
[1, 2, 3, 4]

Однако в нашей постановке задачи специально говорилось, что нужно проверить, содержат ли первые четыре элемента число 9. Если мы просто воспользуемся приемом среза, например так:

for i in arr[:4]:
    if i == '9':
       return true

Он вернет true, даже если мы передадим ему массив вроде ['1','9'], поскольку срез всегда будет работать.

Чтобы поймать это условие, мы сначала проверяем, меньше ли длина списка 4, потому что если это так, то оно автоматически нарушает условие.

person Burhan Khalid    schedule 30.08.2016