在所述列表上添加带有迭代索引号的新字典键时,列表索引超出范围错误

List index out of range error when adding a new dictionary key with iterating index numbers on said list

不打算详细介绍背景。 myquery 运行一个从我的工作数据库中提取的脚本。一切都被放入列表中。它应该从那里将所有内容转储到 Google Sheet,一次一行。当我只需要担心两个变量时效果很好,我可以使用像字典这样的二进制文件。好吧,现在我得到了更多; 4 个类别,每个类别都需要独占一行。

我只需要将列表 (rawskudata) 拆分成一堆分配给字典 (skuandimages) 的较小列表 (componant)。问题出在这一行:

skuandimages[c_list] = [rawskudata[int(c_sku)], rawskudata[int(c_img_url)], rawskudata[int(c_name)], rawskudata[int(c_quantity)]]

我得到 IndexError: list index out of range。

根据我连续盯着它看两个小时并使“indexerror”的每个 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)returns 这个(为保护隐私而修改的数据):

['222001-1', 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/64/Garden_strawberry_%28Fragaria_%C3%97_ananassa%29_single.jpg/440px-Garden_strawberry_%28Fragaria_%C3%97_ananassa%29_single.jpg', 'Strawberry', '1', '222014-1', 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/78/Ripe%2C_ripening%2C_and_green_blackberries.jpg/440px-Ripe%2C_ripening%2C_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']

您一次从 rawskudata 4 中抓取数据,因此您想循环超过 rawskudata

中项目数量的 1/4
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)]]

不需要将所有内容都转换为整数,因为数字已经是整数。也许这只是您在尝试找出 IndexError 时添加的内容,但在这里没有必要。在这种情况下,如果 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 = c_sku + 4c_sku += 4 是 shorthand)。现在无需根据 c_quantity

计算数字

最后的改进。 range 有一个鲜为人知的功能;第三个参数允许我们按 4s 计数而不是按 1s 计数。知道这一点我们真的可以让事情变得简单

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 等,如 iproduct_data[2:] 是一种 shorthand 获取从第二项开始到列表末尾的子列表的方法。