【问题标题】:Conditional checks for JSON key-value pairs being ignored忽略 JSON 键值对的条件检查
【发布时间】:2017-03-05 09:24:00
【问题描述】:

我正在通过返回 JSON 的 Web 调用构建点要素类。 JSON 有点粗略,因为有时记录中不存在键。一旦我有一个有效的 JSON 对象,我就会尝试这样做:

#requests stuff above this

for i in jsonObj:
    try:
        if i['properties']['country']:
            country = i['properties']['country']
        else:
            country = 'UNK'
            print('Country name not found, using {}'.format(country))
    except KeyError, e:
        print('Key error: reason: {}'.format(str(e)))
        pass

#then do all the arcpy FC creation stuff

结果是一大堆带有“原因:'国家'”的关键错误,而不是使用“UNK”的通用“国家”值构建这些行,它会简单地忽略它们并构建要素类,离开出那些点。

我已取出 try 并将其作为条件检查,但它在缺少“国家”键的第一行失败。

总之,我只是想检查一个键值对是否存在;如果不是,则将通用值 'UNK' 分配给 country 变量。

似乎问题的一部分可能是if i['properties']['countries'] 正在检查一个值,而不是密钥本身的存在?如何更有效地检查密钥是否存在?


我已阅读 Check if a given key already exists in a dictionary 并已将我的代码修改为这两个,但都没有产生预期的结果:

for i in jsonObj:
    try:
        # get coordinates first
        if i['geometry']['coordinates']:
            ycoord = float(i['geometry']['coordinates'][1])
            xcoord = float(i['geometry']['coordinates'][0])
            if i['properties']['city'] in i:
                city = i['properties']['city']
            else:
                city = 'UNK'

            if i['properties']['country'] in i:
                country = i['properties']['country']
            else:
                country = 'UNK'

for i in jsonObj:
    try:
        # get coordinates first
        if i['geometry']['coordinates']:
            ycoord = float(i['geometry']['coordinates'][1])
            xcoord = float(i['geometry']['coordinates'][0])
            if 'city' in i:
                city = i['properties']['city']
            else:
                city = 'UNK'

            if 'country' in i:
                country = i['properties']['country']
            else:
                country = 'UNK'

我在每条记录/字典中都有“属性”键,但不能保证我是否有“国家”键。 json 响应中有些行有,有些行没有

【问题讨论】:

  • 你可以试试if 'properties' in i:, not if 'country' in i:`。
  • 每个字典中都有properties 键吗?
  • 是的,我在每条记录/字典中都有'properties'键,但不能保证我是否有'country'键。 json 响应中的某些行有它,有些行没有。

标签: python json geojson


【解决方案1】:

您的最后一次尝试:

if 'country' in i:
    country = i['properties']['country']
else:
    country = 'UNK'

很接近,但你正在管理一个字典,'country' 更有可能成为子字典的键,所以修复方法是:

if 'country' in i['properties']:
    country = i['properties']['country']
else:
    country = 'UNK'

或者甚至更好更短地使用get 和默认值(我推荐最后一个超过快速修复):

country = i['properties'].get('country','UNK')

【讨论】:

  • 转移到 .get() 方法将是我对这个脚本的下一个修改,所以感谢您对它的澄清。所以有了这个,我什至可以完全消除 if-else 检查,是吗?
【解决方案2】:

看来你还没有完全理解 json 的实现。

x = i['geometry']['coordinates']基本上就是y = i['geometry']; x = y['coordinates'],所以需要对每一层进行安全检查,因为i['geometry']不仅会在'geometry'字段不存在时抛出异常,而且返回的对象也必须实现[] ['coordinates'] 工作(所以在这种情况下,它必须是另一个 json object,而不是 string,bool,None 等)

我也相信你的 json 对象是使用 python 字典实现的,所以你可以检查某些字段,例如'geometry' 使用 x.get('geometry') 存在,它将返回其值或 None 对象。你也可以使用city = x.get('city', 'UKN') 来设置默认值(json objectstringboolNone 等),如果它在 dict 中没有找到(python dict.get 方法实现默认处理程序)。

所以最后你应该有这样的东西:

geo = i.get('geometry')
if not geo: return

coords = geo.get('coordinates')
if not coords: return
xcoord, ycoord = float(coords[0]), float(coords[1])

props = i.get('properties')
if not props: return
city = props.get('city', 'UNK')
country = props.get('country', 'UNK')

这是一个草稿,我没有测试它,这也强烈断言你的json object是基于pythondict object

【讨论】:

  • 你说得对,我是 json 的婴儿。感谢您的提示。我不在通常的工作站,但我很乐意在几天内尝试一下并跟进。
  • 我今天早上跑了一遍,它的工作方式与上面相同,但错误处理更好。感谢您的提示!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
  • 2018-02-08
  • 2015-10-20
  • 1970-01-01
  • 2011-01-27
  • 2021-11-18
  • 1970-01-01
相关资源
最近更新 更多