KeyError:使用字典时出现3

时间:2020-10-18 16:25:03

标签: python dataframe dictionary if-statement keyerror

我试图在模拟中计算水的氢键数,其中我有3000个水分子(1000个氧和2000个氢)。所以我为此写了一个代码。

我有一个数据框(df1),其中我的氧原子位于 是3 (0,3,6,...)的倍数,在其他位置是氢原子,并且 原子(xi,yi,zi)的x,y,z坐标。现在进行HB计算 需要两个距离小于3.5的氧原子,即d1<3.5和 我正在计算的一个角度应小于30度,即final < pi/6。 每当我的两个条件都满足时,我就会增加 count 变量。但是现在在这里我需要保持两次检查 两个分子只能有一个氢键(标志用于 它)和一个分子最多可以形成四个HB键( record 使用字典,并在检查此条件错误是 出现在最后一个if语句中)。

现在我已经编写了整个逻辑,但是在结尾的if语句中,我得到了一个错误:KeyError: 3

import math
count=0
record={}

for i in range(0,3000,3):
  for j in range (i+3,3000,3):
    flag=0
    x1=0
    y1=0
    z1=0
    d1=0
    x1=df1['xi'][i]-df1['xi'][j]
    y1=df1['yi'][i]-df1['yi'][j]
    z1=df1['zi'][i]-df1['zi'][j]
    d1=math.sqrt((x1**2)+(y1**2)+(z1**2))

    if (d1<3.5):
      if(flag==0):
        for k in range(1,3,1):
            x2=0
            y2=0
            z2=0
            d2=0
            x2=df1['xi'][i+k]-df1['xi'][i]
            y2=df1['yi'][i+k]-df1['yi'][i]
            z2=df1['zi'][i+k]-df1['zi'][i]
            d2=math.sqrt((x2**2)+(y2**2)+(z2**2))

            x3=0
            y3=0
            z3=0
            d3=0
            x3=df1['xi'][i+k]-df1['xi'][j]
            y3=df1['yi'][i+k]-df1['yi'][j]
            z3=df1['zi'][i+k]-df1['zi'][j]
            d3=math.sqrt((x3**2)+(y3**2)+(z3**2))

            final=0
            final=math.acos(((d2**2)+(d3**2)-(d1**2))/(2*(d2*d3)))

            if (final<0.523):

              if j not in record:
                record.update({j:1})
              else :
                record[j]=record[j]+1

              if i not in record:
                record.update({i:1})
              else :
                record[i]=record[i]+1

              count=count+1
              flag=1

      if (flag==0):
        for l in range(1,3,1):
            x2=0
            y2=0
            z2=0
            d2=0
            x2=df1['xi'][i]-df1['xi'][j+l]
            y2=df1['yi'][i]-df1['yi'][j+l]
            z2=df1['zi'][i]-df1['zi'][j+l]
            d2=math.sqrt((x2**2)+(y2**2)+(z2**2))

            x3=0
            y3=0
            z3=0
            d3=0
            x3=df1['xi'][j]-df1['xi'][j+l]
            y3=df1['yi'][j]-df1['yi'][j+l]
            z3=df1['zi'][j]-df1['zi'][j+l]
            d3=math.sqrt((x3**2)+(y3**2)+(z3**2))

            final=0
            final=math.acos(((d2**2)+(d3**2)-(d1**2))/(2*(d2*d3)))

            if (final<0.523):

              if j not in record:
                record.update({j:1})
              else :
                record[j]=record[j]+1

              if i not in record:
                record.update({i:1})
              else :
                record[i]=record[i]+1

              count=count+1
              flag=1

    if (record[j]==4 or record[i]==4):
     break

    else:
      continue

1 个答案:

答案 0 :(得分:0)

当您尝试访问字典中不存在的键时,会引发KeyError。如果在if (record[j]==4 or record[i]==4)行中发生这种情况,则意味着ji设置为3,而record[3]不存在。

如果record[3]应该存在,则需要弄清楚为什么未设置它。从您的代码看来,只有通过record条件的情况下,特定值才会被添加到if (d1<3.5)字典中。如果不是,则查找该值将失败。

如果预计dict中某些键会丢失,那么有两种方法可以避免KeyError:

  1. 改为使用record.get(j)。方法get(key[, default]docs)返回提供的默认值,如果未提供默认值,则返回None,而不引发KeyError。
  2. 如果您不希望密钥完全丢失,请为record使用defaultdict来将密钥的值初始化为0(如果它是首次访问时将其丢失)。这也可以让您简化一些代码,所以代替:
record = {}

for j in <...>
    if j not in record:
        record.update({j:1})
    else :
        record[j]=record[j]+1

您可以这样做:

from collections import defaultdict

record = defaultdict(int) # calls `int()` for missing keys, which returns 0

for j in <...>
    record[j]+=1