如何使用for循环在JSON中创建多个记录(aka对象)

时间:2019-04-08 00:30:51

标签: json python-3.x for-loop

Python noob在这里。我正在尝试创建一个Python脚本,以使用for循环生成具有多个itemAvailability记录(又称对象)的JSON自动生成JSON,JSON消息的结构和基数如下:

messageHeader[1]
-itemId [1]
--itemAvailability [1-*]

itemAvailability记录使系统知道该项目何时可用,并且我正在尝试创建一个循环,以便它将在接下来的28天中创建随机的itemAvailability时间。我尝试过在线查找,但是看不到任何能解决此特定问题的东西,我已经测试了功能和for循环隔离,因此知道它们可以工作,但无法通过for循环在JSON中创建多个itemAvailability记录。我可以进行一对一转换,但是一旦尝试任何形式的循环,它就会爆炸或不会创建多个itemAvailability记录。我很难在网上看到任何东西,因为它们能够使用带有相同类型的多个对象的python创建JSON,到目前为止,我拥有的代码是

    import json
from datetime import datetime, timedelta
import math
from random import randrange


def starttimestamp(curr, delta):
    start = datetime.min + math.ceil((curr - datetime.min) / delta) * delta
    formatted = start.strftime("%Y-%m-%dT%H:%M:%SZ")
    return formatted


def endtimestamp(curr, delta):
    end = datetime.min + math.ceil((curr - datetime.min) / delta) * delta + timedelta(minutes=randrange (30,600,30))
    formatted = end.strftime("%Y-%m-%dT%H:%M:%SZ")
    return formatted


timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")

data = {'messageId': "theId", 'transId': 'theOtherId',
        'createdTimestamp': timestamp, 'itemList': [{
            'itemId': "I"}]}

today = datetime.now()
next_day = timedelta(days = 1)

date_counter = 0
for days in range(0, 28):
    date_counter += 1
    today += next_day
    curr = today
    data['itemList'][0]['itemAvailability'] = {
    'startTimestamp': starttimestamp(curr, timedelta(minutes=30)),
    'endTimestamp' : endtimestamp(curr, timedelta(minutes=30))}

with open(r'C:\\Somewhere.json', 'w') as outfile:
json.dump(data, outfile)

我得到的是这样:

{
"messageId": "theId",
"transId": "theOtherId",
"createdTimestamp": "2019-04-08T00:32:47Z",
"itemList": [{
    "itemId": "I",
    "itemAvailability": {
        "startTimestamp": "2019-05-06T01:00:00Z",
        "endTimestamp": "2019-05-06T06:30:00Z",
        "availability": "A"
    }
}]

}

但是我想要的是这样的:

{
"messageId": "theId",
"transId": "theOtherId",
"createdTimestamp": "2019-04-08T00:32:47Z",
"itemList": [{
        "itemId": "I",
        "itemAvailability": {
            "startTimestamp": "2019-05-06T01:00:00Z",
            "endTimestamp": "2019-05-06T06:30:00Z",
            "availability": "A",
            "itemAvailability": {
                "startTimestamp": "2019-05-06T01:00:00Z",
                "endTimestamp": "2019-05-06T06:30:00Z",
                "availability": "A",
                "itemAvailability": {
                    "startTimestamp": "2019-05-06T01:00:00Z",
                    "endTimestamp": "2019-05-06T06:30:00Z",
                    "availability": "A",
                    "itemAvailability": {
                        "startTimestamp": "2019-05-06T01:00:00Z",
                        "endTimestamp": "2019-05-06T06:30:00Z",
                        "availability": "A",
                        "itemAvailability": {
                            "startTimestamp": "2019-05-06T01:00:00Z",
                            "endTimestamp": "2019-05-06T06:30:00Z",
                            "availability": "A",
                            "itemAvailability": {
                                "startTimestamp": "2019-05-06T01:00:00Z",
                                "endTimestamp": "2019-05-06T06:30:00Z",
                                "availability": "A"
                            }
                        }
                        ]
                    }

1 个答案:

答案 0 :(得分:1)

A json object is just a dictionary or hash table. This means that EVERY key must be unique.

For Example:

d[1] = 'a' # d = {1: 'a'}
d[1] = 'b' # d = {1: 'b'} - Note that the value for 1 is overridden.

So from your code:

for days in range(0, 28):
    date_counter += 1
    today += next_day
    curr = today

    # Note the key for your `data` dictionary never changes.
    # Your code is always writing to the same key: ['itemList'][0]['itemAvailability'].
    data['itemList'][0]['itemAvailability'] = {
    'startTimestamp': starttimestamp(curr, timedelta(minutes=30)),
    'endTimestamp' : endtimestamp(curr, timedelta(minutes=30))}

To solve this, and meet your desired output

import json
from datetime import datetime, timedelta
import math
from random import randrange


def starttimestamp(curr, delta):
    start = datetime.min + math.ceil((curr - datetime.min) / delta) * delta
    formatted = start.strftime("%Y-%m-%dT%H:%M:%SZ")
    return formatted


def endtimestamp(curr, delta):
    end = datetime.min + math.ceil((curr - datetime.min) / delta) * delta + timedelta(minutes=randrange (30,600,30))
    formatted = end.strftime("%Y-%m-%dT%H:%M:%SZ")
    return formatted


timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")

data = {'messageId': "theId", 'transId': 'theOtherId',
        'createdTimestamp': timestamp, 'itemList': [{
            'itemId': "I"}]}

today = datetime.now()
next_day = timedelta(days = 1)

date_counter = 0

# We need the ability to move a pointer down the dictionary.
temp_data = data['itemList'][0]

for days in range(0, 28):
    date_counter += 1
    today += next_day
    curr = today
    temp_data['itemAvailability'] = { # Create the dict for our current level
    'startTimestamp': starttimestamp(curr, timedelta(minutes=30)),
    'endTimestamp' : endtimestamp(curr, timedelta(minutes=30)),
    'availability': 'A',
    'itemAvailability': dict()
    }
    temp_data = temp_data['itemAvailability'] # Move the pointer down one level

print(json.dumps(data, indent=4))

Note: I do not recommend nesting your payload this way. If every object is the same then you shouldn't nest it but instead list it.

date_counter = 0

data['itemList'][0]['itemAvailability'] = list()

for days in range(0, 28):
    date_counter += 1
    today += next_day
    curr = today
    data['itemList'][0]['itemAvailability'].append({
    'startTimestamp': starttimestamp(curr, timedelta(minutes=30)),
    'endTimestamp' : endtimestamp(curr, timedelta(minutes=30)),
    'availability': 'A',
    })

print(json.dumps(data, indent=4))