【问题标题】:KeyError in dict but Key existsdict中的KeyError但Key存在
【发布时间】:2019-01-30 15:56:40
【问题描述】:

我正在解析一个看起来像这样的字典:

data = {0: {},
        1: {'1': 'M_AVL_002'},
        2: {'2': 'CloudServiceAvailability'},
        3: {'3': 'P_001'},
        4: {'4': '2.592 x10^6'},
        5: {'4': 'second'},
        6: {'3': 'E_001'},
        7: {'4': ' 100 x (P_001- M_TQD_001)/P_001'},
        8: {'4': 'ISO80000'},
        9: {'4': 'percentage'},
        10: {'1': 'M_TQD_001'},
        11: {'2': 'TotalQualifiedDowntime'},
        12: {'3': 'E_001'},
        13: {'4': '?(M_QDT_001)'},
        14: {'4': 'ISO80000'},
        15: {'4': 'second'}}

我想访问一些像这样的值:

for metric in XML.findall("{http://standards.iso.org/iso-iec/19086/-2/ed-1/en}Metric"):
        for row,value in data.items() :
            if (row==0):
                pass
            else :
                for col,v in value.items():
                    if (col=="1"):
                        metric.set('id',str(data[row][col]))
                    if (col=="2"):
                        metric.set('description',str(data[row][col]))
                    if (col=="3"):
                        if (str(data[row][col]).startswith("E")):
                            metric.find('{http://standards.iso.org/iso-iec/19086/-2/ed-1/en}Expression').set("id",str(data[row][col]))
                            metric.find('{http://standards.iso.org/iso-iec/19086/-2/ed-1/en}Expression').set("expressionStatement",str(data[str(int(row)+1)][str(int(col)+1)]))
                            metric.find('{http://standards.iso.org/iso-iec/19086/-2/ed-1/en}Expression').set("expressionLanguage",str(data[str(int(row)+2)][str(int(col)+1)]))
                            metric.find('{http://standards.iso.org/iso-iec/19086/-2/ed-1/en}Expression').set("unit",str(data[str(int(row)+3)][str(int(col)+1)]))
                        elif (str(data[row][col]).startswith("P")):
                            for param in metric.findall('{http://standards.iso.org/iso-iec/19086/-2/ed-1/en}Parameter'):
                                if(str(data[row][col])==param.get('id')):
                                    a=str(data[row][col])
                                    print(str(int(row)+1),str(int(col)+1))
                                    b=str(data[str(int(row)+1)][str(int(col)+1)])
                                    c=str(data[str(int(row)+2)][str(int(col)+1)])
                                    param.set("id",a)
                                    param.set("parameterStatement",b)
                                    param.set("unit",c)
                                else:
                                    pass
                        elif (str(data[row][col]).startswith("R")):
                            for rule in metric.findall('{http://standards.iso.org/iso-iec/19086/-2/ed-1/en}Rule'):
                                if(str(data[row][col])==rule.get('id')):
                                    a=str(data[row][col])
                                    b=str(data[str(int(row)+1)][str(int(col)+1)])
                                    rule.set("id",a)
                                    rule.set("ruleStatement",b)
                                else :
                                    pass

但是,我在分配了b 的行上有一个KeyError。我尝试打印 rowcol 并检查 row+1 和 col+1 是否是键,它们是。

在程序崩溃 row=6 和 col=3 的情况下,因此在这个位置有一个值,但对于 row=7 和 col=4 也是如此,我有:KeyError :'7'

【问题讨论】:

  • 分配b 时,您使用的是[str(col+1)]。我认为这可能应该是[str(int(col) + 1)],因为您的第二个键是一个字符串,并且必须对数字执行加法。
  • @Rachel 我也试过了也没用
  • 你的问题是Python中字符串和数字是不同的类型,数字2不等于字符串'2'
  • 你能说出你对ab的预期输出吗?
  • @JackMoody a='E_001' 和 b 应该等于 ' 100 x (P_001- M_TQD_001)/P_001'

标签: python python-3.x dictionary keyerror


【解决方案1】:
for row,value in data.items() :
    for col,v in value.items():
        a=data[row][col]
        b=data[row+1][str(int(col)+1)]

但是在 row=4 和 col=4 点,你会得到错误,因为 data 中没有 data[5]['5'] 元素。

请注意 data['4'] 和 data[4] 是不同的东西。这就是为什么您需要通过正确的键获取 dict 元素的原因。

【讨论】:

  • 那么当我在 row=3 col =3 点并尝试通过 b=str(data[str(int(row)+1)][str(int(col)+1)]) 访问数据 [4][4] 时,我为什么会得到 KeyError: '4'
  • 因为你正在尝试访问'4',当它是4时
  • 所有 dict 键都是字符串不是吗?
  • 不,它们可以是任何不可变类型。所以 data['4'] 和 data[4] 是不同的东西
  • 你一开始有 int 键,然后是 str 键。所以你需要data[row+1][str(int(col)+1)]
【解决方案2】:

外部字典的键是整数,因此不应将它们转换为字符串。

for row,value in data.items() :
    for col,v in value.items():
        a=data[row][col]
        b=data[row+1][str(int(col)+1)]

但是,您将再次拥有KeyError!打印您尝试访问的密钥。

for row,value in data.items() :
    for col,v in value.items():
        a=data[row][col]
        print(row+1, str(int(col)+1))

你会得到:

2 2
3 3
4 4
5 5
6 5
7 4
8 5
9 5
10 5
11 2
12 3
13 4
14 5
15 5
16 5

并非所有这些都是有效的。所以,'KeyError in dict but Key exists' 不是一个真实的陈述!

【讨论】:

  • 这是正确的。数据集对该特定算法无效。
  • 当然我知道当我尝试访问但我从不尝试访问不可用的密钥时......
  • 我对算法做了一个概括@Rachel,但我从来没有尝试访问不存在的东西
  • 我已经做到了,这就是为什么我在 stackoverflow 上询问,因为我无法弄清楚
猜你喜欢
  • 2017-02-17
  • 2021-05-29
  • 2013-12-16
  • 1970-01-01
  • 2014-09-09
  • 2020-02-26
  • 2019-05-01
  • 2021-07-15
  • 1970-01-01
相关资源
最近更新 更多