Python3.4中'dict_keys'无法索引问题及Python2代码适配方案
解决Python3中推特地理数据抓取脚本的dict_keys索引错误
你遇到的这个错误完全是Python2和Python3的核心差异导致的:在Python2里,dict.keys()返回的是一个可直接索引的列表,但Python3里它返回的是dict_keys视图对象——这个对象只能迭代,不能用[1]这种索引方式取值。
直接修复报错代码
先看你报错的那行代码,原来的写法依赖于字典键的索引顺序,在Python3里我们可以先把dict_keys转换成列表,就能正常索引了:
# 把dict_keys转换成列表再索引 coords_keys = list(tweet['coordinates'].keys()) user_data["features"]["primary_geo"] = str(tweet['coordinates'][coords_keys[1]][1]) + ", " + str(tweet['coordinates'][coords_keys[1]][0])
不过这里有个隐藏的坑:字典的键顺序在Python3.7之前是不固定的,原来的Python2代码依赖keys()[1]取到coordinates键其实是不安全的。推特返回的coordinates字段结构是固定的(当存在时,是{"type": "Point", "coordinates": [经度, 纬度]}),所以更可靠的写法是直接通过键名访问,完全不用依赖索引:
# 直接获取经纬度列表:推特coordinates结构是[经度, 纬度] lon_lat = tweet['coordinates']['coordinates'] # 拼接成"纬度, 经度"的格式 user_data["features"]["primary_geo"] = str(lon_lat[1]) + ", " + str(lon_lat[0])
这种写法不仅解决了Python3的兼容性问题,还避免了字典键顺序变化带来的潜在bug。
修复脚本里的其他Python3兼容性问题
你的完整脚本还有几个Python2到Python3的适配点需要修改:
- print语句改为print函数:Python3里
print是内置函数,所有原来的print "xxx"都要改成print("xxx"),比如:# 原代码 print "The file included " + str(len(all_users)) + " unique users who tweeted with or without geo data" # 修改后 print("The file included " + str(len(all_users)) + " unique users who tweeted with or without geo data") - 删除无效代码:脚本里这两行是错误的,会导致额外报错,直接删掉即可:
tweet_coords = list(tweet['coordinates'][tweet['coordinates']]).keys() tweet_coords2 = list(tweet['coordinates'][tweet['coordinates']]).keys()
最终修改后的关键代码片段
针对tweet['coordinates']的处理部分,修改后应该是这样:
if tweet['coordinates']: # 直接获取经纬度列表,避免依赖字典键索引 lon_lat = tweet['coordinates']['coordinates'] user_data["features"]["primary_geo"] = str(lon_lat[1]) + ", " + str(lon_lat[0]) user_data["features"]["geo_type"] = "Tweet coordinates"
这样修改后,脚本就能在Python3.4下正常运行了。
内容的提问来源于stack exchange,提问作者Bonzay
相关产品推荐
相关产品推荐

