#python #list #dictionary #index-error
Вопрос:
Не буду вдаваться в подробности на заднем плане. Функция myquery запускает скрипт, который извлекается из моей рабочей базы данных. Все складывается в список. Оттуда предполагается выгрузить все в таблицу Google, по одной строке за раз. Отлично работало, когда мне приходилось беспокоиться только о двух переменных, и я мог использовать что-то двоичное, например словарь. Что ж, теперь у меня есть еще; 4 категории, каждая из которых должна быть на своей линии.
Мне просто нужно разделить список (rawskudata) на несколько меньших списков (компонент), назначенных словарю (skuandimages). Проблема в этой строке:
skuandimages[c_list] = [rawskudata[int(c_sku)], rawskudata[int(c_img_url)], rawskudata[int(c_name)], rawskudata[int(c_quantity)]]
и я получаю ошибку индекса: индекс списка выходит за пределы диапазона.
основываясь на том, что я смотрел на него буквально два часа подряд и делал каждый результат поиска Google для «ошибки индекса» фиолетовым, это ДОЛЖНО сработать. в списке, из которого он извлекается, есть номер индекса. я сверился со всевозможными печатными заявлениями. почему?. почему бы и нет. я хочу умереть
mycursor = mydb.cursor() skuandimages = { } myquery2 = #insert top secret query here mycursor.execute(myquery2) rawskudata = [] c_tag = 0 c_sku = 0 c_img_url = 1 c_name = 2 c_quantity = 3 print(mycursor) for xy in mycursor: for yx in range(2,6): rawskudata.append(str(xy[yx])) print(rawskudata) for z in range(0,len(rawskudata)): #skuandimages[str(x[2]) "-" str(x[3])] = x[4] c_list = "componant" str(c_tag) skuandimages[c_list] = [rawskudata[int(c_sku)], rawskudata[int(c_img_url)], rawskudata[int(c_name)], rawskudata[int(c_quantity)]] #skuandimages[c_list] = [x for x] c_sku = c_quantity 1 c_img_url = c_quantity 2 c_name = c_quantity 3 c_quantity = c_quantity 4 c_tag = 1
Печать(rawskudata) возвращает это (данные изменены для обеспечения конфиденциальности):
['222001-1', 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/64/Garden_strawberry_(Fragaria_×_ananassa)_single.jpg/440px-Garden_strawberry_(Fragaria_×_ananassa)_single.jpg', 'Strawberry', '1', '222014-1', 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/78/Ripe,_ripening,_and_green_blackberries.jpg/440px-Ripe,_ripening,_and_green_blackberries.jpg', 'Blackberry', '1', '222053-1', 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/e3/Oranges_-_whole-halved-segment.jpg/440px-Oranges_-_whole-halved-segment.jpg', 'Oranges', '1', '222123-1', 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Autumn_Red_peaches.jpg/440px-Autumn_Red_peaches.jpg', 'Peaches', '1', '222203-1', 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Pears.jpg/440px-Pears.jpg', 'Pears', '1']
Комментарии:
1. Отладка может быть неприятной, и обычно, чем проще ошибка, тем больше времени требуется, чтобы ее обнаружить. Добро пожаловать в SO, кто — нибудь сможет помочь. В качестве первого шага — не могли бы вы включить вывод
print(rawskudata)
(утверждение передfor z in ...
) в свой вопрос
Ответ №1:
Вы получаете данные из rawskudata
4 одновременно, поэтому вы хотите зациклиться на 1/4 количества элементов в rawskudata
for z in range(0, int(len(rawskudata)/4)):
Но есть более простой способ сделать это. Вы можете заменить все, что происходит после строки mycursor.execute(myquery2)
, на:
for xy in mycursor: skuandimages["componant" str(c_tag)] = [xy[2], xy[3], xy[4], xy[5]] c_tag = c_tag 1
Отзывы
Ниже я написал несколько отзывов о написанном вами коде, которые, надеюсь, помогут вам в изучении Python.
Когда вы получаете данные
for xy in mycursor: for yx in range(2,6): rawskudata.append(str(xy[yx]))
Было бы лучше использовать имена переменных
for row in mycursor: for sku_item in range(2,6):
Хотя именование может не иметь большого значения в небольших приложениях, оно становится одной из самых важных вещей при написании кода в более крупных приложениях, а также облегчает задачу, если вы вернетесь к своему коду в будущем и попытаетесь выяснить, что он делает.
Строка rawskudata.append(str(xy[yx]))
преобразует данные в строку. Обычно лучше оставить данные как есть, пока они вам действительно не понадобятся в виде строки. Таким образом, если бы вы хотели сделать с ним что-то еще, например, сравнить количество продукта, у вас была бы возможность сделать это.
В строке for z in range(0,len(rawskudata)):
вместо использования имени переменной z
обычно используется i
сокращение index
, когда вы берете индекс каждого элемента в списке, подобном этому, или некоторые люди будут использовать имя переменной _
для переменных, которые вы на самом деле никогда не используете в коде. Хотя обычно это красный флаг, что вы закодировали что-то более громоздким способом, когда вместо этого используете шаблон for i in range(0, len(some_list)):
for some_value in some_list:
.
В таких словарях, как skuandimages
у вас, есть ключи и значения. Переменную c_list
можно было бы назвать c_key
лучше, поскольку она является ключом словаря, а не списком.
Линия
skuandimages[c_list] = [rawskudata[int(c_sku)], rawskudata[int(c_img_url)], rawskudata[int(c_name)], rawskudata[int(c_quantity)]]
Не нужно преобразовывать все в целые числа, так как числа уже являются целыми числами. Возможно, это было просто то, что вы добавили, пытаясь выяснить ошибку индекса, но здесь в этом нет необходимости. В этой ситуации мы хотели бы, чтобы ошибка естественным образом произошла, если бы одна из переменных, таких как c_sku, не была целым числом.
Линии
c_sku = c_quantity 1 c_img_url = c_quantity 2 c_name = c_quantity 3 c_quantity = c_quantity 4
Кажется странным, что вы основываете все на количестве. Я бы предпочел создать новую переменную, имеющую базовое значение для этой итерации, а затем вы можете добавить 1, 2, 3, 4, и т.д. к нему. Также чаще всего поля продукта получают до того, как вы добавляете их в skuandimages
что-то вроде:
product_start_index = 0 for _ in range(0, int(len(rawskudata)/4)): sku = rawskudata[product_start_index 0] img_url = rawskudata[product_start_index 1] name = rawskudata[product_start_index 2] quantity = rawskudata[product_start_index 3] key = "component" product_start_index skuandimages[key] = [sku, img_url, name, quantity] product_start_index = 4
Или, возвращаясь к этим 4 строкам, другой альтернативой было бы
c_sku = 4 c_img_url = 4 c_name = 4 c_quantity = 4
Добавляя 4 к этим переменным каждый раз, когда вы проходите цикл. ( c_sku = 4
сокращенно c_sku = c_sku 4
от ). И теперь нет необходимости основываться на цифрах c_quantity
Одно последнее улучшение. Существует менее известная функция range
; третий параметр, который позволяет нам считать на 4, а не на 1. Зная это, мы действительно можем все упростить
for i in range(0, len(rawskudata), 4): sku = rawskudata[i 0] img_url = rawskudata[i 1] name = rawskudata[i 2] quantity = rawskudata[i 3] skuandimages["component" i] = [sku, img_url, name, quantity]
Но, как я уже упоминал ранее, лучшим решением было бы создавать skuandimages
с самого начала, а не rawskudata
:
for xy in mycursor: skuandimages["componant" str(c_tag)] = [xy[2], xy[3], xy[4], xy[5]] c_tag = c_tag 1
И если вы действительно хотите сделать вещи компактными, это можно переписать как
for i, product_data in enumerate(mycursor): skuandimages["componant " str(i)] = product_data[2:]
enumerate
даст нам обоим количество, 1, 2, 3 и т. Д. i
, Каждый раз , когда мы проходим цикл, Вместе с фактическими данными о продукте. product_data[2:]
это сокращенный способ получения подсписка, начинающегося со второго пункта и заканчивающегося в конце списка.
Комментарии:
1. Красивые. Ты-святой. Я был слишком глубоко погружен в свои мысли. Это прекрасно работает. Спасибо.