AYST • J 2023-03-21 11:39 采纳率: 75%
浏览 53
已结题

字典相互嵌套去除指定字段指定部分的全部数据

问题遇到的现象和发生背景

想要将seq:7后面的iboy里的scd:9,scd:7取出来该怎么做

尝试过的解决方法
[{abc:1212,iheader:[  {seq:7,iboy:[{scd:9},{scd:7}],seq:8,iboy:[{scd:8},{sdf:4}]     }            ]               }]


  • 写回答

4条回答 默认 最新

  • AhcaoZhu 2023-03-21 14:02
    关注

    首先,你这个数据结构叫人眼花缭乱。其中有一些错误:在同一字典中,关键字不重复。(第二层花括号seq, iboy是重复的)
    其次,不知道你这个数据结构是固定不变的(普遍的情况),还是仅为举例说明嵌套的层次多(特例的情况)。
    针对不同的情况,有不同的解决方法。

    方法一: 不改变数据结构

    就以你这个例子来说明,如何访问到每一个元素。(嵌套以固定的格式)
    为了方便,改正了关键字重复的错误。另外,对关键字变量进行了模拟赋值。(因你程序不完整)

    我不知道,你这个 sdf 是不是 scd 的笔误。姑且原样照抄吧。

    # 原题:[{abc: 1212, iheader: [{seq: 7, iboy: [{scd: 9}, {scd: 7}], seq: 8, iboy: [{scd: 8}, {sdf: 4}]}]}]
    # 模拟变量,方便输出:
    abc, iheader, seq7, iboy7, scd9, scd7, seq8, iboy8, scd8, sdf, scd = ('abc', 'iheader', 'seq7', 'iboy7', 'scd9', 'scd7', 'seq8', 'iboy8', 'scd8', 'sdf', 'scd')
    li = [{abc: 1212, iheader: [{seq7: 7,
                                 iboy7: [{scd: 9}, {scd: 7}],
                                 seq8: 8,
                                 iboy8: [{scd: 8}, {sdf: 4}]
                                 }
                                ]
           }
          ]
    
    print(li)
    print(f'abc = {li[0][abc]}')
    print(f'iheader = {li[0][iheader]}')
    print(f'seq7 = {li[0][iheader][0][seq7]}')
    print(f'iboy7 = {li[0][iheader][0][iboy7]}')
    print(f'scd9 = {li[0][iheader][0][iboy7][0][scd]}')
    print(f'scd7 = {li[0][iheader][0][iboy7][1][scd]}')
    print(f'seq8 = {li[0][iheader][0][seq8]}')
    print(f'iboy8 = {li[0][iheader][0][iboy8]}')
    print(f'scd8 = {li[0][iheader][0][iboy8][0][scd]}')
    print(f'sdf = {li[0][iheader][0][iboy8][1][sdf]}')
    

    以下是程序运行结果:

    # [{'abc': 1212, 'iheader': [{'seq7': 7, 'iboy7': [{'scd': 9}, {'scd': 7}], 'seq8': 8, 'iboy8': [{'scd': 8}, {'sdf': 4}]}]}]
    # abc = 1212
    # iheader = [{'seq7': 7, 'iboy7': [{'scd': 9}, {'scd': 7}], 'seq8': 8, 'iboy8': [{'scd': 8}, {'sdf': 4}]}]
    # seq7 = 7
    # iboy7 = [{'scd': 9}, {'scd': 7}]
    # scd9 = 9
    # scd7 = 7
    # seq8 = 8
    # iboy8 = [{'scd': 8}, {'sdf': 4}]
    # scd8 = 8
    # sdf = 4
    

    方法二,修改数据结构,主要是采取 namedtuple 来嵌套。

    当然了,方法有很多种。

    scd, sdf = 'scd', 'sdf'
    iboy = namedtuple('iboy', ['scd1', 'scd2'])
    iheader = namedtuple('iheader', ['seq', 'iboy'])
    data = namedtuple('data', ['abc', 'iheader'])
    iboy7 = iboy(scd1={scd: 9}, scd2={scd: 7})
    iboy8 = iboy(scd1={scd: 8}, scd2={sdf: 4})
    iheader7 = iheader(seq=7, iboy=iboy7)
    iheader8 = iheader(seq=8, iboy=iboy8)
    data1 = data(abc=1212, iheader=[iheader7, iheader8])
    li = [data1]
    print(li)
    print(li[0].abc)
    print(li[0].iheader)
    print(li[0].iheader[0].seq)
    print(li[0].iheader[1].iboy)
    print(li[0].iheader[1].iboy.scd2[sdf])
    

    运行结果如下(举例只是列举了一部分):

    # [data(abc=1212, iheader=[iheader(seq=7, iboy=iboy(scd1={'scd': 9}, scd2={'scd': 7})), iheader(seq=8, iboy=iboy(scd1={'scd': 8}, scd2={'sdf': 4}))])]
    # 1212
    # [iheader(seq=7, iboy=iboy(scd1={'scd': 9}, scd2={'scd': 7})), iheader(seq=8, iboy=iboy(scd1={'scd': 8}, scd2={'sdf': 4}))]
    # 7
    # iboy(scd1={'scd': 8}, scd2={'sdf': 4})
    

    方法三:数据结构是动态的

    假如不知列表或字典嵌套了几层,可以用递归函数。
    这里,关键字的命名很重要,否则你也不知道取的是第几层的什么变量。

    基本搞清楚了你的需求,写了一个相对完整的代码,从网页抓取、到数据解析,直到数据保存。

    import requests
    import csv
    url = '...'     # 这里替换成你的网址
    head = {...}    # 这里替换成你的请示头
    res = requests.get(url=url, headers=head).json()    # 确定网页发送的是json数据。
    
    # 预定义字段
    data_keys = ['AllocatedID','SortSeq','cInvCode','cInvStd','cComUnitName','BaseQtyN','BaseQtyD','iQuantity','cSRPolicy','iPlanDefault']
    # 一行数据的值:11个字段
    Vars = []
    # 读取数据,这里替换成 json 对象的名称。
    lis = res['result']
    # 保存数据的文件
    with open('保存数据.csv', encoding='utf-8', mode='a', newline='') as f:
        csv_w = csv.writer(f)
    # 解析数据
    for dic in lis:
        for iHeader in dic.keys():
            li_iHeaders = dic['iHeader']
            for Seq_dic in li_iHeaders:
                li_iBody = Seq_dic['iBody']
                for data_dict in li_iBody:
                    for i in range(len(data_keys)):
                        Vars[i] = data_dict[data_keys[i]]
                        csv_w.writerow(Vars)
    f.close()
    

    说明如下:

    • 循环的层次有点多,这是假设你的每层数据都有展开的情况。
      必要时,外层循环可以拿掉,例如:第一层, dic = lis[0]
    • 不知你的数据库类型,所以写在 csv 里了,可以直接用 Excel 打开,检查数据读取是否正确、完整。

      Alt


      本答复由 大侠(AhcaoZhu)原创,转载请声明。
      链接: https://blog.csdn.net/Ahcao2008
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 4月16日
  • 已采纳回答 4月8日
  • 创建了问题 3月21日

悬赏问题

  • ¥50 三种调度算法报错 有实例
  • ¥15 关于#python#的问题,请各位专家解答!
  • ¥200 询问:python实现大地主题正反算的程序设计,有偿
  • ¥15 smptlib使用465端口发送邮件失败
  • ¥200 总是报错,能帮助用python实现程序实现高斯正反算吗?有偿
  • ¥15 对于squad数据集的基于bert模型的微调
  • ¥15 为什么我运行这个网络会出现以下报错?CRNN神经网络
  • ¥20 steam下载游戏占用内存
  • ¥15 CST保存项目时失败
  • ¥20 java在应用程序里获取不到扬声器设备