【问题标题】:KeyError: 3 while using dictionaryKeyError: 3 使用字典时
【发布时间】:2021-02-01 12:55:00
【问题描述】:

我正在尝试在有 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

【问题讨论】:

    标签: python dataframe dictionary if-statement keyerror


    【解决方案1】:

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

    如果record[3] 应该存在,您需要弄清楚为什么它没有被设置。从您的代码看来,如果某个特定值通过了if (d1&lt;3.5) 条件,它似乎只会被添加到record 字典中。如果没有,则查找该值将失败。

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

    1. 请改用record.get(j)get(key[, default](docs) 方法返回提供的默认值,如果未提供默认值,则返回 None,而不是引发 KeyError。
    2. 如果您不指望键完全丢失,请使用defaultdict 代替record,如果键在第一次访问时丢失,则将其值初始化为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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-06
      相关资源
      最近更新 更多