【问题标题】:Scraping a List[Dict] with more dictionaries inside; getting range errors抓取包含更多字典的 List[Dict];获取范围错误
【发布时间】:2022-01-12 13:47:51
【问题描述】:

我有一个包含这张图片中信息的字典列表:

我正在尝试进入“儿童”列表并提取文件大小、filetpye、名称和类型(未图示!)。在某些资产上,子列表是空的,所以我想跳过这些。

我有这个循环:

children_in_review_link = {}
for i in range(len(items_in_review_link)):
    #pprint.pprint(items_in_review_link[i])
    if items_in_review_link[i][0]['asset']['children'] != []:
        review_link_children.append(items_in_review_link[i][0]['asset']['children'])
        print(items_in_review_link[i][0]['asset']['children'])
        for j in range(len(items_in_review_link[i][0]['asset']['children'])):
            children_in_review_link = {
                'child_name': items_in_review_link[i][0]['asset']['children'][j]['name'],
                'child_type': items_in_review_link[i][0]['asset']['children'][j]['type'],
                'child_size': items_in_review_link[i][0]['asset']['children'][j]['filesize'],
                'child_filetype': items_in_review_link[i][0]['asset']['children'][j]['filetype'],
            }
            review_link_children.append(children_in_review_link)

pprint.pprint(review_link_children)

但我收到if items_in_review_link[i][0]['asset']['children'] != []: 行的“列表超出范围”错误

我已将pprint.pprint(items_in_review_link[i][0]) 行作为检查,它会在范围内的最后一项上返回“列表索引超出范围”错误。

我怎样才能正确地做到这一点?

【问题讨论】:

  • 可能从将中间结果分配给变量开始,以避免一遍又一遍地重复相同的表达式。
  • 接下来,首选for x in list_of_things: use(x) 而不是for i in range(len(list_of_things)): use(list_of_things[i])
  • 如果你也需要索引也可以这样做:for i, x in enumerate(list_of_things): do_something

标签: python range screen-scraping


【解决方案1】:

请记住,像列表和字典这样的可迭代对象是可迭代的:您可以直接迭代它们的成员。使用类似的东西

for i in range(len(my_list)):
    do_something(my_list[i])

就是所谓的反模式。相反,做

for item in my_list:
    do_something(item)

这将修复您的“列表索引超出范围”错误,因为您不会使用范围。

cmets 中的建议也非常好:将item[0]["asset"]["children"] 分配给另一个中间变量,这样您就不必一遍又一遍地重复它。

【讨论】:

  • 我不确定仅此一项是否能解决任何错误,因为对于for i in range(len(my_list)),没有i 应该超出my_list 的范围。
  • @mkrieger1 对,我不确定超出范围的错误来自哪里,但我的想法是,如果您消除范围(无论如何都是不必要的),您可能会得到更易理解的实际出现问题的错误消息。
  • 谢谢!今天试试这个,会更新它的进展情况!
【解决方案2】:

您使用了额外的 [0] 。它不是列表列表。使用此代码。

    children_in_review_link = {}
    for i in range(len(items_in_review_link)):
    #pprint.pprint(items_in_review_link[i])
    if items_in_review_link[i][0]['asset']['children'] != []:
        review_link_children.append(items_in_review_link[i]['asset']['children'])
        print(items_in_review_link[i]['asset']['children'])
        for j in range(len(items_in_review_link[i]['asset']['children'])):
            children_in_review_link = {
                'child_name': items_in_review_link[i]['asset']['children'][j]['name'],
                'child_type': items_in_review_link[i]['asset']['children'][j]['type'],
                'child_size': items_in_review_link[i]['asset']['children'][j]['filesize'],
                'child_filetype': items_in_review_link[i]['asset']['children'][j]['filetype'],
            }
            review_link_children.append(children_in_review_link)

    pprint.pprint(review_link_children)

总是更好用

for item in item_list:
   print(item)

如果你也想要索引,那么像这样使用枚举,

for i,item in enumerate(item_list):
   print(i,item)

【讨论】:

  • 谢谢!那个额外的 [0] 快把我逼疯了!感谢指导!
  • 没问题的兄弟!
【解决方案3】:

假设你的结构如图所示:

results = []
for item in items_in_review_link:
    for child in item['asset']['children']:
        results.append(
            {
                'child_name': child['name'],
                'child_type': child['type'],
                'child_size': child['filesize'],
                'child_filetype': child['filetype']
            }
        )

或者作为单行:

results = [
    {
        'child_name': child['name'],
        'child_type': child['type'],
        'child_size': child['filesize'],
        'child_filetype': child['filetype']
    }
    for item in items_in_review_link
    for child in item['asset']['children']
]

将来您可能会发现一次只做一步很有用。

for item in items_in_review_link:
    print(item)

这让您可以一步一步地对结果采取行动,而不是试图一次解决所有问题。

此外,正如其他人所提到的,每当您发现自己在做 range(len(some_iterable)) 时,您可能都很难做到。

关于 python 的最好的事情之一是for 循环默认将可迭代解包到变量中的方式。如果您的最终目标是无论如何都要访问该变量,那么您只是在以更模糊的方式使用更多步骤。

【讨论】:

  • 好提示,谢谢。
猜你喜欢
  • 2022-12-07
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多