You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python函数distances出现KeyError 'R'及距离计算问题求助

帮你解决Python函数的KeyError及其他问题

嘿,我来一步步帮你排查代码里的问题,先从你遇到的KeyError: 'R'说起:

1. KeyError的直接原因

你代码里写了cities[city1[0]],这里city1是传入的城市名字符串(比如'Raleigh'),city1[0]取的是字符串的第一个字符'R',而你的cities字典里根本没有键为'R'的条目,自然就触发了KeyError。正确的做法是先通过cities[city1]获取该城市的经纬度元组,再通过索引0和1分别取纬度和经度,比如:

lat1, lon1 = cities[city1]
lat2, lon2 = cities[city2]

这样后续计算就不会出错了。

2. 其他隐藏问题

除了KeyError,你的代码还有几个影响功能的问题:

(1)覆盖了传入的cities参数

你在函数内部重新定义了cities = {'Raleigh':(...), ...},这会完全替换掉调用时传入的cities参数——不管外部传什么字典进来,函数里都用你自己写的这个,这完全不符合作业要求(作业要求接收外部的cities字典),所以必须删掉这行。

(2)大圆距离公式的括号错误+弧度转换缺失

你原来的acos表达式括号配对错误,导致计算逻辑完全偏离正确的大圆距离公式。另外还有个容易忽略的点:math.sin/math.cos的参数要求是弧度,而我们的经纬度是角度值,不转换的话计算结果会完全错误。

正确的大圆距离公式(弧度版)应该是:
6371 * math.acos( math.sin(lat1_rad)*math.sin(lat2_rad) + math.cos(lat1_rad)*math.cos(lat2_rad)*math.cos(lon1_rad - lon2_rad) )

(3)欧氏距离计算错误

欧氏距离的正确公式是√[(lat2-lat1)² + (lon2-lon1)²],但你现在的代码:

  • 索引错误(和KeyError的问题一样,用了city2[0]而不是cities[city2][0])
  • 平方的位置错误:应该是每个差值先平方,再相加,而不是只给第一个纬度差值平方
  • 多了一个多余的**2:相当于把开根号后的结果又平方,等于没开根号,完全不符合要求

(4)导入语句的位置问题

按照Python的编码规范,import math应该放在文件的开头,而不是函数内部,这样更清晰也更高效。

修正后的完整代码

import math

def distances(city1: str, city2: str, cities: dict):
    """
    Description: Takes in two strings (city1 and city2), searches to see if those strings are found in the cities dictionary. If they are, this calculates the great circle distance and the Euclidean distance between the cities.
    >>> distances('Raleigh', 'Centreville', {'Raleigh':(35.7796, -78.6382), 'Tianjin':(39.129498, 117.251038), 'Centreville':(32.9446, -87.1386), 'Los Angeles':(34.0522, -118.2437), 'Houston':(29.749907, -95.358421)})
    (912.0632333576412, 8.53343436)
    >>> distances('NYC', 'Tianjin', {'Raleigh':(35.7796, -78.6382), 'Tianjin':(39.129498, 117.251038), 'Centreville':(32.9446, -87.1386), 'Los Angeles':(34.0522, -118.2437), 'Houston':(29.749907, -95.358421)})
    (nan, nan)
    """
    if city1 in cities and city2 in cities:
        # 获取两座城市的经纬度
        lat1, lon1 = cities[city1]
        lat2, lon2 = cities[city2]
        
        # 角度转弧度(math三角函数要求输入弧度)
        lat1_rad = math.radians(lat1)
        lon1_rad = math.radians(lon1)
        lat2_rad = math.radians(lat2)
        lon2_rad = math.radians(lon2)
        
        # 计算大圆距离
        great_circle = 6371 * math.acos(
            math.sin(lat1_rad) * math.sin(lat2_rad) +
            math.cos(lat1_rad) * math.cos(lat2_rad) * math.cos(lon1_rad - lon2_rad)
        )
        
        # 计算欧氏距离
        euclidean = math.sqrt(
            (lat2 - lat1)**2 + (lon2 - lon1)**2
        )
        
        return (great_circle, euclidean)
    else:
        return (math.nan, math.nan)

关键修改说明

  1. 把import math移到了文件开头,符合Python编码规范。
  2. 删掉了函数内部重新定义的cities字典,保留传入的参数,满足作业要求。
  3. 用lat1, lon1 = cities[city1]正确获取经纬度,彻底解决KeyError问题。
  4. 补充了角度转弧度的步骤,确保三角函数计算的正确性。
  5. 修正了大圆距离和欧氏距离的公式,让计算逻辑完全符合数学定义。
  6. 更新了doctest的示例,把cities字典直接写入测试用例,避免测试时找不到变量的问题。

现在你再运行测试用例,就不会再出现KeyError,而且计算结果也完全正确了。

内容的提问来源于stack exchange,提问作者ashnotallyson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:02:50