Как создать несколько записей (или объектов) в JSON, используя цикл for - PullRequest
3 голосов
/ 08 апреля 2019

Питон нуб здесь. Я пытаюсь создать сценарий Python для автоматической генерации JSON с несколькими записями itemAvailability (aka Objects), используя цикл for для их генерации, сообщение JSON структурировано и количество элементов следующим образом:

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

Запись itemAvailability сообщает системе, когда элемент доступен, и я пытаюсь создать цикл, чтобы он создавал случайные времена itemAvailability в течение следующих 28 дней. Я пробовал смотреть онлайн, но не вижу ничего, что решает эту конкретную проблему, я протестировал функции и цикл for в отдельности, поэтому знаю, что они работают, но не могу получить цикл for для создания более одной записи itemAvailability в JSON. Я могу получить конвертацию один в один, но как только я пытаюсь зациклить любую форму, она взрывается или не создает более одной записи itemAvailability. Я изо всех сил пытаюсь увидеть что-нибудь в Интернете за возможность создания JSON с использованием Python с несколькими объектами одного типа, код, который у меня пока есть:

    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 Ответ

1 голос
/ 08 апреля 2019

Объект json - это просто dictionary или хеш-таблица. Это означает, что ключ EVERY должен быть уникальным.

Например:

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

Итак, из вашего кода:

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))}

Чтобы решить эту проблему и достичь желаемого результата

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))

Примечание: Я не рекомендую таким образом вкладывать вашу полезную нагрузку. Если все объекты одинаковы, вы не должны вкладывать их, а вместо этого list.

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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...