【问题标题】:Finding items in a nested dictionary in a json object在 json 对象的嵌套字典中查找项目
【发布时间】:2018-12-08 20:18:42
【问题描述】:

我正在尝试将 json 对象作为输入,并找到符合特定条件的项目数。 json 对象结构在嵌套的 python 字典中,例如:

businesses= ["{\"hours\":
            {
            \"tuesday\": [[\"11:30\", \"23:00\"]],
            \"thursday\": [[\"11:30\", \"23:00\"]],
            \"wednesday\": [[\"11:30\", \"23:00\"]],
            \"friday\": [[\"11:30\", \"23:00\"]],
            \"sunday\": [[\"9:00\", \"23:00\"]],
            \"monday\": [[\"11:30\", \"23:00\"]],
            \"saturday\": [[\"11:30\", \"23:00\"]]
            },
            \"name\": \"XYZ\"
        }"]

该结构中将有多个项目。我遇到的问题是编写 for 循环以进入关卡,并搜索周日上午 10 点之前营业的企业。

所以是这样的:

def count_businesses(object):
    for i in object:
        for j in i:
        ....

但是当我达到那个级别时,它似乎会输出字典中的每一个字母。另外,我不确定如何编写函数来查找打开的日期和时间,对我来说必须在上午 10 点之前找到星期日,然后返回计数。时间在这个对象的字典内的数组中,如图所示。

任何帮助将不胜感激!

【问题讨论】:

    标签: arrays json python-3.x dictionary


    【解决方案1】:

    python 字典是什么似乎有些混淆。 businesses 中的数组中的数据实际上是 JavaScript 对象表示法 (JSON) 中的字符串,python 将其视为字符串。要将其用作 python 字典,您需要使用 python 的 json 库对其进行转换。转换看起来像,

    import json
    
    python_obj = json.loads(json_str)
    

    您提供的对象是一个 JSON 字符串数组,例如

    businesses = ["{\"hours\":"
                "{"
                "\"tuesday\": [[\"11:30\", \"23:00\"]],"
                "\"thursday\": [[\"11:30\", \"23:00\"]],"
                "\"wednesday\": [[\"11:30\", \"23:00\"]],"
                "\"friday\": [[\"11:30\", \"23:00\"]],"
                "\"sunday\": [[\"9:00\", \"23:00\"]],"
                "\"monday\": [[\"11:30\", \"23:00\"]],"
                "\"saturday\": [[\"11:30\", \"23:00\"]]"
                "},"
                "\"name\": \"XYZ\""
            "}"]
    

    python 字典的数组如下所示

    businesses = [
        {
            "hours":{
                "tuesday":[["11:30","23:00"]],
                "thursday":[["11:30","23:00"]],
                "wednesday":[["11:30","23:00"]],
                "friday":[["11:30", "23:00"]],
                "sunday":[["9:00", "23:00"]],
                "monday":[["11:30", "23:00"]],
                "saturday":[["11:30", "23:00"]]
            },
            "name":"XYZ"
        }
    ]
    

    因此,您看到它输出每个字母的原因是因为您正在遍历字符串,而不是 python 字典。当 python 遍历一个字符串时,它会遍历每个字符。就像下面这样。

    string_data = "123456789"
    # will iterate through each character
    for i in string_data:
        print(i) # will print 9 times each time outputting a character in order
    

    至于函数,您需要确保在进行时间比较时,您使用的是 Python 时间对象而不是字符串,因为这样可以准确地比较时间。我不完全确定为什么时间会列在嵌套数组中,例如[["11:30","23:00"]],因此如果其他业务的数据格式不同,您可能需要修改以下函数。

    这是一个描述你需要什么的函数。

    import json, datetime
    
    businesses = ["{\"hours\":"
                "{"
                "\"tuesday\": [[\"11:30\", \"23:00\"]],"
                "\"thursday\": [[\"11:30\", \"23:00\"]],"
                "\"wednesday\": [[\"11:30\", \"23:00\"]],"
                "\"friday\": [[\"11:30\", \"23:00\"]],"
                "\"sunday\": [[\"9:00\", \"23:00\"]],"
                "\"monday\": [[\"11:30\", \"23:00\"]],"
                "\"saturday\": [[\"11:30\", \"23:00\"]]"
                "},"
                "\"name\": \"XYZ\""
            "}"]
    
    
    def count_businesses(business_list):
        """
        :param business_list: An array of business in JSON to query from
        :return: Int of the count of businesses that are open on Sunday before 10 am
        """
    
        # initialize the array that will contain the businesses that meet the search criteria
        businesses_found = []
    
        # python time object of 10:00am that will be used to check against
        opening_business_time = datetime.time(hour=10)
    
        # iterate through each busineses to check if it meets the search criteria
        for business in business_list:
    
            # since each business is in JSON, we convert it into a Python object
            business_obj = json.loads(business)
    
            # Look into the 'hours' key, then the 'sunday' key and get the first item in the array. ( i.e ["11:30","23:00"])
            sunday_hours = business_obj["hours"]["sunday"][0]
    
            # read in the sunday opening hours as a string from the first value of the array. {i.e "11:30")
            sunday_opening_hours_str = sunday_hours[0]
    
            # convert the sunday opening hours into a time object so it can be compared.
            # '%H:%M' looks for the format HH:MM in a string.
            # for more reference. https://docs.python.org/3.6/library/datetime.html#strftime-and-strptime-behavior
            sunday_opening_hours_time = datetime.datetime.strptime(sunday_opening_hours_str, '%H:%M').time()
    
            # if sunday opening hours is before 10 am
            if sunday_opening_hours_time < opening_business_time:
    
                # add the business object to the list
                businesses_found.append(business_obj)
    
        # returns the count of the businesses that met the search criteria
        return len(businesses_found)
    
    
    total = count_businesses(businesses)
    
    print(total)
    

    【讨论】:

    • 非常感谢,现在我对这个问题有了更好的理解!
    • 当然没问题!如果您有任何其他问题,请随时提出
    • 还有一个问题,假设输入根本不包含星期天,这段代码会抛出错误,因为我们希望所有输入中都包含“星期天”。有没有办法在函数中处理它?
    • 当通过dictionary["key"] 表示法访问密钥时,python 期望该密钥存在。您可以使用dictionary.get("key") 表示法,如果键存在则返回值,如果键不存在则返回None。您可以使用它来检查密钥是否存在。或者,您可以使用dictionary.get("key", False),因为第二个参数是在字典中找不到该键时将返回的值。
    • 非常感谢,这很有道理。我将使用第二个选项,因此代码接受可能根本不包含日期的 json 字符串,在这种情况下我可以返回 none
    【解决方案2】:

    将此添加为星期日的空检查条件。

    if("sunday" in business_obj["hours"])

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      • 2012-12-23
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 1970-01-01
      • 2020-05-24
      相关资源
      最近更新 更多